{"openapi":"3.0.1","info":{"title":"ControlMap API","version":"v1"},"servers":[{"url":"https://api.scalepad.com"}],"tags":[{"name":"Health"},{"name":"Risks"},{"name":"Evidences"},{"name":"Documents"},{"name":"Reports"},{"name":"Frameworks"}],"paths":{"/controlmap/v1/clients/{client_id}/evidences/search":{"post":{"tags":["Evidences"],"summary":"List Client Evidences","description":"Returns a paginated list of evidences belonging to the specified client.\n\nSupports filtering with PII, sorting, and cursor-based pagination.\n","operationId":"01_evidenceApi","parameters":[{"name":"client_id","in":"path","description":"Unique identifier of the client whose evidences are being retrieved.","required":true,"schema":{"type":"string"},"example":"365bcf1e-a26b-4abc-ad9a-8607e2f43910"}],"requestBody":{"description":"Request payload containing filters, pagination and sorting options.\n\n**Filtering**\n\nFilters must be passed inside the `filter` object.\n\nSupported fields:\n`code`, `title`, `owner.email`\n\n**Examples**\n\n```\n\"filter\": {\n  \"code\": \"eq:EV-30\",\n  \"title\": \"eq:Provide evidence that HTTPS / TLS and other\",\n  \"owner.email\": \"john.doe@example.com\"\n}\n```\n\n**Supported operators**\n- `eq` — exact match\n- `in` — comma-separated list\n\nExample:\n\n```\n\"code\": \"in:EV-30,EV-31\"\n```\n\n**Optional Flags**\n\n- `fetch_items`\n  - true (default): Include evidence items\n  - false: Return summary only\n\n- `evidence_request`\n  - true: Include evidence request metadata\n  - false (default): Exclude evidence-request metadata\n\n**Pagination**\n\n- `page_size` default = 50\n- `page_size` max = 200\n\n**Cursor Pagination**\n\n- `cursor` must be Base64 encoded.\n\n**Sorting**\n\nAllowed fields:\n\n`created_at`, `updated_at`\n\nSorting rules:\n- Ascending → `created_at` or `+created_at`\n- Descending → `-created_at`\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceQueryRequest"},"examples":{"Example Request":{"description":"Illustrates usage of filters, pagination, cursor-based navigation, and sorting in a single request.Illustrates usage of filters, pagination, cursor-based navigation, and sorting in a single request.","value":{"filter":{"code":"eq:EV-30","title":"eq:Provide evidence that HTTPS / TLS and other","owner.email":"john.doe@example.com"},"fetch_items":true,"evidence_request":false,"page_size":50,"cursor":"YWJjMTIz","sort":"-created_at"}}}}},"required":true},"responses":{"200":{"description":"Ok","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ClientEvidencePaginatedResponse"},"examples":{"SuccessResponse":{"summary":"Successful paginated response","description":"Represents a successful response containing a list of Evidence.","value":{"client":{"id":"365bcf1e-a26b-4abc-ad9a-8607e2f43910","name":"Joel Tech","tenant_id":"joel1"},"evidence_summary":{"completed":3,"review":0,"in_progress":0,"not_started":117,"not_applicable":0,"total":120,"completion_percentage":2.5},"evidences":{"data":[{"id":99,"code":"EV-1","title":"Automatically generated listing of new hires during the given audit period.","description":null,"repeats":false,"evidence_requests":[{"id":99,"code":"EV-1-1","title":null,"description":null,"status":"Not Started","created_by":{"id":2,"name":"Joel Tech","email":"john.doe@example.com"},"owner":{"id":1,"name":"Joel Tech","email":"john.doe@example.com"},"documents":[],"due_date":"2026-05-31T00:00:00","updated_at":"2026-02-04T15:28:26","created_at":"2025-10-08T08:35:34","implementation_notes":"test notes"}],"evidence_request_summary":{"Not Started":5,"In Progress":2,"Review":0,"Completed":0,"Not Applicable":0,"total":7},"created_by":{"id":2,"name":"Joel Tech","email":"john.doe@example.com"},"owner":null,"schedule":null,"refresh_status":"Somewhat Current","updated_date":"2025-12-16T09:23:33","created_date":"2025-10-08T08:35:34"}],"total_count":120,"next_cursor":"eyJpZCI6MTUwfQ=="}}}}}}},"400":{"description":"Bad Request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"invalidSortField":{"summary":"Invalid sort field or order","description":"Returned when the request contains an invalid or unsupported sort parameter. The client must provide a valid sort field.","value":{"errors":[{"code":"BAD_REQUEST","title":"Validation error.","detail":"Allowed fields: created_at, updated_at. Use '-' for descending, '+' or no prefix for ascending."}]}},"invalidFilterField":{"summary":"Invalid filter field","description":"Returned when the request includes an unsupported or invalid filter field. The client must use a valid, filterable field.","value":{"errors":[{"code":"BAD_REQUEST","title":"Invalid Filter","detail":"Filtering is not supported for the field 'abc'. Please use a valid filterable field."}]}},"ValidationError_PageSize":{"summary":"Page size exceeds maximum allowed limit","description":"Returned when the request contains invalid pagination","value":{"errors":[{"code":"BAD_REQUEST","title":"Validation error.","detail":"page size must be less than or equal to 200"}]}}}}}},"401":{"description":"Unauthorized","content":{"application/json":{"examples":{"ErrorResponse":{"description":"Returned when authentication fails due to a missing, invalid, or expired Bearer access token.","value":{"errors":[{"code":"UNAUTHORIZED","title":"Invalid or expired token.","detail":"The provided JWT is invalid or has expired. Please authenticate again and include a valid Bearer token."}]}}}}}},"404":{"description":"Not Found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"notFound":{"summary":"ErrorResponse","description":"The requested client or tenant was not found, or the API path/version is invalid or unsupported.","value":{"errors":[{"code":"NOT_FOUND","title":"Client Not Found","detail":"The specified client does not exist or is not associated with the tenant."}]}}}}}},"500":{"description":"Internal Server Error","content":{"application/json":{"examples":{"ErrorResponse":{"description":"Represents a generic server failure. The client request was valid, but processing failed due to an internal system error.","value":{"errors":[{"code":"INTERNAL_SERVER_ERROR","title":"Internal server error.","detail":"An unexpected error occurred on the server. Please try again later."}]}}}}}}},"security":[{"apiKey":[]}]}},"/controlmap/v1/clients/{client_id}/reports":{"post":{"tags":["Reports"],"summary":"List Client Reports","description":"Retrieves a paginated list of reports for a client, with support for filtering with PII, sorting, and cursor-based pagination.\n","operationId":"01_listClientReports","parameters":[{"name":"client_id","in":"path","description":"Unique identifier of the client whose reports are being retrieved.","required":true,"schema":{"type":"string"},"example":"365bcf1e-a26b-4abc-ad9a-8607e2f43910"}],"requestBody":{"description":"Request payload containing filters, pagination and sorting options.\n\n**Filtering**\n\nFilters must be passed inside the `filter` object.\n\nSupported fields:\n- `report_name`\n- `status`\n- `owner.email`\n\n**Examples**\n\n```\n\"filter\": {\n  \"report_name\": \"eq:Supplier Score Report (SPRS)\",\n  \"status\": \"eq:Progress\",\n  \"owner.email\": \"eq:john.doe@example.com\"\n}\n```\n\n**Supported status values**\n\n`Progress`, `Completed`, `Fail`\n\n**Supported operators**\n- `eq` — exact match\n- `in` — comma-separated list\n\nExample:\n\n```\n\"status\": \"in:Progress,Completed\"\n```\n\n**Pagination**\n\n- `page_size` default = 50\n- `page_size` max = 200\n\n**Cursor Pagination**\n\n- `cursor` must be Base64 encoded.\n\n**Sorting**\n\nAllowed fields:\n\n`created_at`, `report_name`, `status`\n\nSorting rules:\n- Ascending → `created_at` or `+created_at`\n- Descending → `-created_at`\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReportQueryRequest"},"examples":{"Example Request":{"description":"Request to fetch Reports with filters, pagination, and sorting.","value":{"filter":{"report_name":"eq:Supplier Score Report (SPRS)","status":"eq:Progress","owner.email":"eq:john.doe@example.com"},"page_size":50,"cursor":"YWJjMTIz","sort":"-created_at"}}}}},"required":true},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ClientReportPaginatedResponse"},"examples":{"SuccessResponse":{"summary":"Successful paginated response","description":"Represents a successful response containing a list of Report.","value":{"client":{"id":"365bcf1e-a26b-4abc-ad9a-8607e2f43910","name":"Joel Tech","tenant_id":"joel"},"report_summary":{"total":121,"progress":2,"completed":89,"failed":1},"reports":{"total_count":106,"next_cursor":"eyJpZCI6NTB9","data":[{"id":1,"report_name":"Assessment Report.doc","program":null,"created_by":{"id":1,"name":"Joel King","email":"john.doe@example.com"},"created_at":"2026-03-13T19:26:21","status":"Completed"}]}}}}}}},"400":{"description":"Bad Request — Invalid input or business rule violation.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"invalidFilter":{"summary":"Invalid filter field","description":"Triggered when filtering is attempted on a non-filterable field.","value":{"errors":[{"code":"BAD_REQUEST","title":"Invalid Filter","detail":"Filtering is not supported for the field 'statusdf'. Please use a valid filterable field."}]}},"invalidSort":{"summary":"Invalid sort value","description":"Triggered when sort parameter contains an unsupported field or format.","value":{"errors":[{"code":"BAD_REQUEST","title":"Validation error.","detail":"Invalid sort value. Allowed fields: created_at, report_name, status with optional + or -."}]}},"badRequest":{"summary":"Invalid path or request values","description":"Returned when the provided clientId is not registered","value":{"errors":[{"code":"INVALID_CLIENT","title":"Invalid client identifier.","detail":"The clientId 'Joel Tech' is invalid or not registered. Please verify the client ID in the request path."}]}}}}}},"401":{"description":"Unauthorized - Authentication required","content":{"application/json":{"examples":{"ErrorResponse":{"description":"Returned when authentication fails due to a missing, invalid, or expired Bearer access token.","value":{"errors":[{"code":"UNAUTHORIZED","title":"Invalid or expired token.","detail":"The provided JWT is invalid or has expired. Please authenticate again and include a valid Bearer token."}]}}}}}},"404":{"description":"Resource Not Found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"ErrorResponse":{"description":"The requested client or tenant was not found, or the API path/version is invalid or unsupported.","value":{"errors":[{"code":"NOT_FOUND","title":"Resource Not Found","detail":"The requested resource could not be found. Please verify the API path and version."}]}}}}}},"500":{"description":"Server Internal Error — Unexpected failure on the server.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"ErrorResponse":{"summary":"Unexpected server-side failure","description":"Represents a generic server failure. The client request was valid, but processing failed due to an internal system error.","value":{"errors":[{"code":"INTERNAL_SERVER_ERROR","title":"Internal server error.","detail":"An unexpected error occurred on the server. Please try again later."}]}}}}}}},"security":[{"apiKey":[]}]}},"/controlmap/v1/clients/assessments/common/summary":{"get":{"tags":["Assessments"],"summary":"Clients Assessment Overview","description":"Returns paginated Assessment Overview for all partner clients.\n\nThis endpoint supports:\n- Cursor-based pagination\n- Sorting\n- Filtering\n\n**Use Cases:**\n- Retrieve Assessment Overview across all MSP clients\n- Build partner-level dashboards\n- Analyze Assessment completeness across multiple tenants\n- Paginate large Assessment summary datasets\n","operationId":"01_listClientsAssessmentSummary","parameters":[{"name":"filter[client.tenant_id]","in":"query","description":"Filters records by the `client.tenant_id` field.\n\n**Supported operators:**\n- `eq` — exact match\n- `in` — list-based match\n\n**Examples:**\n- `filter[client.tenant_id]=Joel Tech` — to filter for exact match\n- `filter[client.tenant_id]=eq:Joel Tech` — to filter for exact match\n- `filter[client.tenant_id]=in:Joel Tech,John Tech` — to filter for any match in list\n","schema":{"type":"string"},"example":"eq:Joel Tech"},{"name":"filter[client.name]","in":"query","description":"Filters records by the `client.name` field.\n\n**Supported operators:**\n- `eq` — exact match\n- `in` — list-based match\n\n**Examples:**\n- `filter[client.name]=Joel King` — to filter for exact match\n- `filter[client.name]=eq:Joel King` — to filter for exact match\n- `filter[client.name]=in:Joel King,John` — to filter for any match in list\n","schema":{"type":"string"},"example":"eq:Joel King"},{"name":"page_size","in":"query","description":"Number of records to return per page.\nMust be between **1 and 200**.\nDefault: **50**\n","required":false,"schema":{"type":"integer","format":"int32","default":50,"maximum":200,"minimum":1},"example":50},{"name":"cursor","in":"query","description":"Base64-encoded cursor value used for pagination.\nPass the cursor received from the previous response to fetch the next page.\n","required":false,"schema":{"type":"string","pattern":"^[A-Za-z0-9+/=]*$"},"example":"eyJpZCI6NDQxLCJwYWdlIjoxfQ=="},{"name":"sort","in":"query","description":"Single sort field (comma-separated lists are not accepted by this endpoint).\n\nPrefix with `-` for descending. Optional `+` prefix or no prefix means ascending.\n\n**Allowed values:** `client.name`, `client.tenant_id`\n","required":false,"schema":{"type":"string","pattern":"^(?:[+-]|\\s)?(client.tenant_id|client.name)$"},"example":"client.name"}],"responses":{"200":{"description":"SuccessResponse","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/ClientAssessmentSummaryResponse"}},"examples":{"SuccessResponse":{"description":"Shows aggregated assessment summary across clients.","value":{"data":[{"client":{"id":"365bcf1e-a26b-4abc-ad9a-8607e2f43910","name":"Joel Tech","tenant_id":"joel1"},"assessment_summary":{"yes":30,"no":30,"partially":20,"not_answered":40,"not_applicable":10,"answering_percentage":77.7,"total":130}},{"client":{"id":"365bcf1e-a26b-4abc-ad9a-8607e2f43911","name":"Vistel Tech","tenant_id":"joel2"},"assessment_summary":{"yes":20,"no":25,"partially":15,"not_answered":50,"not_applicable":5,"answering_percentage":65,"total":115}}],"total_count":2,"next_cursor":"eyJpZCI6NDQxLCJwYWdlIjoyfQ=="}}}}}},"400":{"description":"Bad Request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"validationError":{"summary":"Invalid query parameter or operator","description":"Returned when the request contains an invalid filter parameter or an unsupported query operator.","value":{"errors":[{"code":"VALIDATION_ERROR","title":"Invalid Query Parameter","detail":"Invalid filter or unsupported operator."}]}},"invalidSortField":{"summary":"Invalid sort field","description":"Returned when the request contains an invalid or unsupported sort parameter. The client must provide a valid sort field.","value":{"errors":[{"code":"BAD_REQUEST","title":"Validation error.","detail":"Allowed fields:client.tenant_id, client.name. Use '-' for descending, '+' or no prefix for ascending."}]}},"invalidFilterField":{"summary":"Invalid filter field","description":"Returned when the request includes an unsupported or invalid filter field. The client must use a valid, filterable field.","value":{"errors":[{"code":"BAD_REQUEST","title":"Invalid Filter","detail":"Filtering is not supported for the field 'abc'. Please use a valid filterable field."}]}}}}}},"401":{"description":"Unauthorized - Authentication required","content":{"application/json":{"examples":{"ErrorResponse":{"description":"Returned when authentication fails due to a missing, invalid, or expired Bearer access token.","value":{"errors":[{"code":"UNAUTHORIZED","title":"Invalid or expired token.","detail":"The provided JWT is invalid or has expired. Please authenticate again and include a valid Bearer token."}]}}}}}},"404":{"description":"Resource Not Found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"ErrorResponse":{"description":"The requested client or tenant was not found, or the API path/version is invalid or unsupported.","value":{"errors":[{"code":"NOT_FOUND","title":"Resource Not Found","detail":"The requested resource could not be found. Please verify the API path and version."}]}}}}}},"500":{"description":"Internal Server Error","content":{"application/json":{"examples":{"ErrorResponse":{"description":"Represents a generic server failure. The client request was valid, but processing failed due to an internal system error.","value":{"errors":[{"code":"INTERNAL_SERVER_ERROR","title":"Internal server error.","detail":"An unexpected error occurred on the server. Please try again later."}]}}}}}}},"security":[{"apiKey":[]}]}},"/controlmap/v1/clients/health":{"get":{"tags":["Health"],"summary":"List Clients Compliance Health Metrics","description":" Returns compliance health metrics for each client of an MSP. By default, returns a paginated list of clients and their overall compliance health. Use `fields` to include additional health metrics like compliance_score, risk_score, frameworks, work_progress, and history.","operationId":"01_listClientsHealth","parameters":[{"name":"filter[client.id]","in":"query","description":"Filters records by using a query string on the field `client.id`.\n\nSupports comparison operators: `eq`, `in`.\n\n**Query examples:**\n- `filter[client.id]=example_value` — exact match\n- `filter[client.id]=eq:example_value` — exact match\n- `filter[client.id]=in:example_value_1,example_value_2,example_value_3` — any match in list\n\n**Example :**\n- `365bcf1e-a26b-4abc-ad9a-8607e2f43910`\n- `eq:365bcf1e-a26b-4abc-ad9a-8607e2f43910`\n","schema":{"type":"string"},"example":"eq:365bcf1e-a26b-4abc-ad9a-8607e2f43910"},{"name":"filter[client.tenant_id]","in":"query","description":"Filters records by using a query string on the field `client.tenant_id`.\n\nSupports comparison operators: `eq`, `in`.\n\n**Query examples:**\n- `filter[client.tenant_id]=example_value` — exact match\n- `filter[client.tenant_id]=eq:example_value` — exact match\n- `filter[client.tenant_id]=in:example_value_1,example_value_2,example_value_3` — any match in list\n\n**Example :** `eq:example_value`\n","schema":{"type":"string"},"example":"eq:example_value"},{"name":"filter[client.name]","in":"query","description":"Filters records by using a query string on the field `client.name`.\n\nSupports comparison operators: `eq`, `in`.\n\n**Query examples:**\n- `filter[client.name]=example_value` — exact match\n- `filter[client.name]=eq:example_value` — exact match\n- `filter[client.name]=in:example_value_1,example_value_2,example_value_3` — any match in list\n\n**Example :** `eq:example_value`\n","schema":{"type":"string"},"example":"eq:example_value"},{"name":"fields","in":"query","description":"Comma-separated components: compliance_score, risk_score, frameworks, work_progress","required":false,"style":"form","explode":false,"schema":{"type":"array","items":{"type":"string"}}},{"name":"page_size","in":"query","description":"Clients per page (default 50, max 200)","required":false,"schema":{"type":"integer","default":50,"maximum":200,"minimum":1}},{"name":"cursor","in":"query","description":"Opaque pagination cursor (Base64)","required":false,"schema":{"type":"string","pattern":"^[A-Za-z0-9+/=]*$"}},{"name":"sort","in":"query","description":"One or more sortable fields, separated by commas.\nPrefix with `+` for ascending or `-` for descending.\n\n**Available values:** `client.name`, `client.tenant_id`, `client.id`\n","required":false,"schema":{"type":"string"},"example":"+client.name,-client.tenant_id"}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ComplianceHealth"},"examples":{"CompleteHealthResponse":{"description":"ComplianceHealth response schema","value":{"data":[{"client":{"id":"365bcf1e-a26b-4abc-ad9a-8607e2f43910","name":"ABC Corporation","tenant_id":"openz"},"compliance_score":{"overall_score":7.8,"score_label":"Average","updated_at":"2025-09-15T17:00:00Z","trend":{"last_30_days":2,"last_60_days":-1,"last_90_days":5}},"risk_score":{"overall_score":85,"risk_level":"Medium","updated_at":"2025-09-15T17:00:00Z","risk_breakdown":{"severe":2,"high":5,"medium":12,"low":8}},"frameworks":[{"framework_id":"soc2","framework_name":"SOC 2","compliance_score":8.2,"score_label":"Healthy","updated_at":"2025-09-15T17:00:00Z","compliance_breakdown":{"compliant":20,"in_review":20,"not_applicable":10,"not_assessed":20,"not_compliant":10,"partially_compliant":10,"compliance_achieved_percentage":20,"total":100},"assessment_breakdown":{"yes":15,"no":15,"partially":20,"not_answered":40,"not_applicable":10,"answering_percentage":90,"total":100}},{"framework_id":"iso27001","framework_name":"ISO 27001","compliance_score":7.5,"score_label":"Average","updated_at":"2025-09-15T17:00:00Z","compliance_breakdown":{"compliant":20,"in_review":20,"not_applicable":10,"not_assessed":20,"not_compliant":10,"partially_compliant":10,"compliance_achieved_percentage":20,"total":100},"assessment_breakdown":{"yes":15,"no":15,"partially":20,"not_answered":40,"not_applicable":10,"answering_percentage":90,"total":100}}],"work_progress":{"evidence":{"completed":45,"review":10,"in_progress":25,"not_started":20,"not_applicable":0,"completion_percentage":45,"total":100},"controls":{"implemented":120,"partially_implemented":35,"not_implemented":45,"in_progress":0,"alternative_implementation":0,"not_applicable":0,"implementation_percentage":60,"total":200},"action_items":{"completed":35,"review":20,"in_progress":25,"not_started":20,"not_applicable":0,"completion_percentage":35,"total":100},"assessments":{"yes":30,"no":30,"partially":20,"not_answered":40,"not_applicable":10,"answering_percentage":77.7,"total":130},"documents":{"approved":10,"in_review":20,"ready_for_approval":30,"in_progress":20,"draft":20,"approved_percentage":10,"total":100},"updated_at":"2025-09-15T17:00:00Z"},"total_count":150,"next_cursor":"eyJjbGllbnRfaWQiOiJ0ZW5hbnQ0NTYifQ=="}]}}}}}},"400":{"description":"Bad Request — Invalid input or business rule violation.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"validationError":{"summary":"Multiple validation or business logic errors","description":"Indicates that one or more request parameters are invalid or violates business validation rules. The client must correct the request and retry.","value":{"errors":[{"code":"VALIDATION_ERROR","title":"Invalid Request Parameter","detail":"One or more query parameters are invalid. Ensure all filters and fields follow the supported format."}]}}}}}},"401":{"description":"Unauthorized - Authentication required","content":{"application/json":{"examples":{"ErrorResponse":{"description":"Returned when authentication fails due to a missing, invalid, or expired Bearer access token.","value":{"errors":[{"code":"UNAUTHORIZED","title":"Invalid or expired token.","detail":"The provided JWT is invalid or has expired. Please authenticate again and include a valid Bearer token."}]}}}}}},"404":{"description":"Not Found — Requested resource does not exist.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"notFound":{"summary":"Client or tenant not found","description":"The requested client or tenant was not found, or the API path/version is invalid or unsupported.","value":{"errors":[{"code":"NOT_FOUND","title":"Resource Not Found","detail":"Requested resource does not exist. Please check the provided identifiers."}]}}}}}},"500":{"description":"Internal server error","content":{"application/json":{"examples":{"ErrorResponse":{"description":"Represents a generic server failure. The client request was valid, but processing failed due to an internal system error.","value":{"errors":[{"code":"INTERNAL_SERVER_ERROR","title":"Internal server error.","detail":"An unexpected error occurred on the server. Please try again later."}]}}}}}}},"security":[{"apiKey":[]}]}},"/controlmap/v1/clients/{client_id}/risks/search":{"post":{"tags":["Risks"],"summary":"Search Client Risks","description":"Retrieves a paginated list of risks associated with a specific client.\n\nSupports filtering with PII, sorting, and cursor-based pagination.\n","operationId":"01_listClientsRisk","parameters":[{"name":"client_id","in":"path","description":"Unique identifier of the client whose risks are being retrieved.","required":true,"schema":{"type":"string"},"example":"365bcf1e-a26b-4abc-ad9a-8607e2f43910"}],"requestBody":{"description":"Request payload containing filters, pagination and sorting options.\n\n**Filtering**\n\nFilters must be passed inside the `filter` object.\n\nSupported fields:\n- `status`\n- `treatment`\n- `owner.email`\n\n**Examples**\n\n```\n\"filter\": {\n  \"status\": \"eq:Not Assessed\",\n  \"treatment\": \"eq:Avoid\",\n  \"owner.email\": \"eq:Joel@example.com\"\n}\n```\n\n**Supported status values**\n\n`Assessed`, `Assessment in progress`, `Closed`, `Needs Remediation`, `Not Assessed`, `Remediated`\n\n**Supported treatment values**\n\n`Avoid`, `Reduce`, `Transfer`, `Share`, `Accept`\n\n**Supported operators**\n- `eq` — exact match\n- `in` — comma-separated list\n\nExample:\n\n```\n\"status\": \"in:Not Assessed,Assessment in progress\"\n```\n\n**Pagination**\n\n- `page_size` default = 50\n- `page_size` max = 200\n\n**Cursor Pagination**\n\n- `cursor` must be Base64 encoded.\n\n**Sorting**\n\nAllowed fields:\n\n`id`, `name`, `current_risk`, `owner.name`\n\nSorting rules:\n- Ascending → `name` or `+name`\n- Descending → `-name`\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RiskQueryRequest"},"examples":{"Example Request":{"description":"Illustrates usage of filters, pagination, cursor-based navigation, and sorting in a single request.Illustrates usage of filters, pagination, cursor-based navigation, and sorting in a single request.","value":{"filter":{"status":"in:Not Assessed,Assessment in progress","treatment":"eq:Avoid","owner.email":"john.doe@example.com   "},"page_size":50,"cursor":"YWJjMTIz","sort":"+name"}}}}},"required":true},"responses":{"200":{"description":"Risks retrieved successfully.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RiskResponse"},"examples":{"SuccessResponse":{"summary":"Successful paginated response","description":"Represents a successful response containing a list of Risk. ","value":{"client":{"id":"365bcf1e-a26b-4abc-ad9a-8607e2f43910","name":"Joel Tech","tenant_id":"joel1"},"risk_summary":{"overall_score":12,"risk_level":"High","updated_at":"2026-02-25T14:40:14","risk_breakdown":{"severe":5,"high":8,"medium":3,"low":0}},"risks":{"data":[{"id":1,"code":"RSK-1","name":"Phishing","description":"Risk of data theft, account takeover, fraudulent transactions on behalf of your company employees","owner":{"id":1,"name":"Joel King","email":"john.doe@example.com"},"status":"Assessment in progress","department":"Sales","risk_category":"Asset Management","treatment":"Avoid","business_impact":"Phishing risk refers to the threat of attackers deceiving employees or users into revealing sensitive information such as login credentials, financial data, or confidential business information through fraudulent emails, messages, or websites.","created_by":{"id":1,"name":"Joel King","email":"john.doe@example.com"},"inherent_risk_score":20,"inherent_risk_label":"Severe","current_risk_score":20,"current_risk_label":"Severe","target_risk_score":1,"target_risk_label":"Low","created_at":"2027-01-30T15:28:17.354Z","updated_at":"2027-01-30T15:28:17.354Z"},{"id":2,"code":"RSK-2","name":"Ransomware","description":"Data loss, theft or simply financial loss due to paying ransom to free up the locked data","owner":{"id":1,"name":"Joel King","email":"john.doe@example.com"},"status":"Assessed","department":"Sales","risk_category":"Business Environment","treatment":"Reduce","business_impact":"Ransomware can cause severe business impact by encrypting critical systems and data, leading to operational downtime, disruption of core business services, loss of productivity, and potential financial losses from ransom payments, system restoration, and incident response efforts. It may also result in data breaches, regulatory penalties, reputational damage, loss of customer trust, and long-term business continuity risks if critical data is not recoverable or recovery is delayed.","created_by":{"id":1,"name":"Joel King","email":"john.doe@example.com"},"inherent_risk_score":20,"inherent_risk_label":"Severe","current_risk_score":20,"current_risk_label":"Severe","target_risk_score":1,"target_risk_label":"Low","created_at":"2027-01-30T15:28:17.354Z","updated_at":"2027-01-30T15:28:17.354Z"}],"total_count":51,"next_cursor":"eyJpZCI6Nn0="}}}}}}},"400":{"description":"Invalid request parameters","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"InvalidCursor":{"summary":"Invalid pagination cursor","description":"Returned when the cursor parameter is not valid Base64","value":{"errors":[{"code":"VALIDATION_ERROR","title":"Invalid Query Parameter","detail":"The 'cursor' parameter must be a valid Base64 string."}]}},"InvalidFilter":{"summary":"Unsupported filter field","description":"Returned when filtering is attempted on a non-filterable field","value":{"errors":[{"code":"BAD_REQUEST","title":"Invalid Filter","detail":"Filtering is not supported for the field 'treatment'. Please use a valid filterable field."}]}},"InvalidClient":{"summary":"Invalid client identifier","description":"Returned when the provided clientId is not registered","value":{"errors":[{"code":"INVALID_CLIENT","title":"Invalid client identifier","detail":"The clientId 'Joel Tech' is invalid or not registered. Please verify the client ID in the request path."}]}}}}}},"401":{"description":"Unauthorized - Authentication required","content":{"application/json":{"examples":{"ErrorResponse":{"description":"Returned when authentication fails due to a missing, invalid, or expired Bearer access token.","value":{"errors":[{"code":"UNAUTHORIZED","title":"Invalid or expired token.","detail":"The provided JWT is invalid or has expired. Please authenticate again and include a valid Bearer token."}]}}}}}},"404":{"description":"Resource Not Found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"Resource Not Found Error":{"description":"The requested client or tenant was not found, or the API path/version is invalid or unsupported.","value":{"errors":[{"code":"NOT_FOUND","title":"Resource Not Found","detail":"The requested resource could not be found. Please verify the API path and version."}]}}}}}},"500":{"description":"Internal server error","content":{"application/json":{"examples":{"ErrorResponse":{"description":"Represents a generic server failure. The client request was valid, but processing failed due to an internal system error.","value":{"errors":[{"code":"INTERNAL_SERVER_ERROR","title":"Internal server error.","detail":"An unexpected error occurred on the server. Please try again later."}]}}}}}}},"security":[{"apiKey":[]}]}},"/controlmap/v1/clients/{client_id}/frameworks/{framework_id}/objectives/search":{"post":{"tags":["Frameworks"],"summary":"Search Client Objectives","description":"Retrieves a paginated list of objectives associated with a specific client.\n\nSupports filtering, sorting, and cursor-based pagination.\n","operationId":"01_searchClientObjectives","parameters":[{"name":"client_id","in":"path","description":"Unique identifier of the client whose requirements are being retrieved.","required":true,"schema":{"type":"string"},"example":"365bcf1e-a26b-4abc-ad9a-8607e2f43910"},{"name":"framework_id","in":"path","description":"Unique identifier of the framework whose requirements are being retrieved.","required":true,"schema":{"type":"integer","format":"int32"},"example":1}],"requestBody":{"description":"Request payload containing filters, pagination and sorting options.\n\n**Filtering**\n\nFilters must be passed inside the `filter` object.\n\n**Supported fields**\n\n- `status`       – Allowed values: `Not Assessed`, `Not Compliant`, `Partially Compliant`, `In Review`, `Compliant`, `Not Applicable`\n\n- `in_scope`        – Filters objectives by scope:\n\n                    - `true`: returns only in-scope objectives\n\n                    - `false`: returns only out-of-scope objectives\n\n**Examples**\n\n```\n\"filter\": {\n  \"status\": \"in:Not Assessed,In Review\",\n  \"in_scope\": \"eq:true\",\n}\n```\n\n**Supported operators**\n- `eq` — exact match\n- `in` — comma-separated list\n\n\n**Pagination**\n\n- `page_size` default = 50\n- `page_size` max = 200\n\n**Cursor Pagination**\n\n- `cursor` must be Base64 encoded.\n\n**Sorting**\n\nAllowed fields:\n\n`name`, `req_id`\n\nSorting rules:\n- Ascending → `name` or `+name`\n- Descending → `-name`\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ClientRequirementSearchRequest"},"examples":{"Example Request":{"description":"Illustrates usage of filters, pagination, cursor-based navigation, and sorting in a single request.Illustrates usage of filters, pagination, cursor-based navigation, and sorting in a single request.","value":{"filter":{"status":"in:Not Assessed,In Review","in_scope":"eq:true          "},"page_size":50,"cursor":"YWJjMTIz","sort":"+name"}}}}},"required":true},"responses":{"200":{"description":"Objectives retrieved successfully.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ClientRequirementSearchResponse"},"examples":{"SuccessResponse":{"summary":"Successful paginated response","description":"Represents a successful response containing a list of objectives.","value":{"client":{"id":"365bcf1e-a26b-4abc-ad9a-8607e2f43910","name":"zoho","tenant_id":"rockp"},"framework":{"id":3,"name":"ISO-27001"},"objective_summary":{"compliant":0,"not_compliant":0,"partially_compliant":0,"not_assessed":61,"in_review":0,"not_applicable":19,"total":140,"complaint_percentage":0},"objectives":{"total_count":140,"next_cursor":"eyJpZCI6MzI4fQ==","data":[{"id":279,"code":"A5.1.1","name":"Policies for information security","description":"<p>A set of policies for information security should be defined, approved by management, published and communicated to employees and relevant external parties.”, “Directives” or “Rules”.</p>","status":"Partially Compliant","level1_code":"A5","level1_name":"Information security policies","level2_code":"A5.1","level2_name":"Management direction for information security","created_at":"2025-09-16T05:45:01","updated_at":"2025-09-16T05:45:01","in_scope":true,"type":"controls","documents":[{"id":19,"name":"Information Security Policy","code":"POL-19"}],"evidences":[{"id":102,"name":"Procedures for handling job role changes, reassignments and promotions","code":"EV-4"}],"action_items":[{"id":217,"name":"Not Performed: Does the organization facilitate the implementation of data protection controls?","code":"AI-1"}]}]}}}}}}},"400":{"description":"Invalid request parameters","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"InvalidCursor":{"summary":"Invalid pagination cursor","description":"Returned when the cursor parameter is not valid Base64","value":{"errors":[{"code":"VALIDATION_ERROR","title":"Invalid Query Parameter","detail":"The 'cursor' parameter must be a valid Base64 string."}]}},"InvalidFilter":{"summary":"Unsupported filter field","description":"Returned when filtering is attempted on a non-filterable field","value":{"errors":[{"code":"BAD_REQUEST","title":"Invalid Filter","detail":"Filtering is not supported for the field 'treatment'. Please use a valid filterable field."}]}},"InvalidClient":{"summary":"Invalid client identifier","description":"Returned when the provided clientId is not registered","value":{"errors":[{"code":"INVALID_CLIENT","title":"Invalid client identifier","detail":"The clientId 'Joel Tech' is invalid or not registered. Please verify the client ID in the request path."}]}}}}}},"401":{"description":"Unauthorized - Authentication required","content":{"application/json":{"examples":{"ErrorResponse":{"description":"Returned when authentication fails due to a missing, invalid, or expired Bearer access token.","value":{"errors":[{"code":"UNAUTHORIZED","title":"Invalid or expired token.","detail":"The provided JWT is invalid or has expired. Please authenticate again and include a valid Bearer token."}]}}}}}},"404":{"description":"Resource Not Found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"ErrorResponse":{"description":"The requested client or tenant was not found, or the API path/version is invalid or unsupported.","value":{"errors":[{"code":"NOT_FOUND","title":"Resource Not Found","detail":"The requested resource could not be found. Please verify the API path and version."}]}}}}}},"500":{"description":"Internal Server Error","content":{"application/json":{"examples":{"ErrorResponse":{"description":"Represents a generic server failure. The client request was valid, but processing failed due to an internal system error.","value":{"errors":[{"code":"INTERNAL_SERVER_ERROR","title":"Internal server error.","detail":"An unexpected error occurred on the server. Please try again later."}]}}}}}}},"security":[{"apiKey":[]}]}},"/controlmap/v1/clients/{client_id}/health":{"get":{"tags":["Health"],"summary":"Get Client Compliance Health Metrics","description":"Returns detailed compliance health metrics for a single MSP client.\n\nThis endpoint is optimized for retrieving the full health snapshot of a client,\nincluding compliance score, risk score, frameworks, and work progress.\n\n- Use this endpoint instead of `/clients/health` when you need data for **one client only**.\n- All scoring fields reflect the most recently computed health values.\n","operationId":"02_ClientHealth","parameters":[{"name":"client_id","in":"path","description":"Unique identifier for the client (ControlMap tenant or client ID).\n\nThe value must match an existing client.\n\n**Examples:**\n- `365bcf1e-a26b-4abc-ad9a-8607e2f43910`\n- `08b538f9-4e59-4bc2-9b13-7df755e06c4f`\n","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK — Client health returned successfully.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Health"},"examples":{"SingleClientHealthExample":{"description":"Health response for a single client","value":{"client":{"id":"365bcf1e-a26b-4abc-ad9a-8607e2f43910","name":"ABC Corporation","tenant_id":"openz"},"compliance_score":{"overall_score":7.8,"score_label":"Average","updated_at":"2025-09-15T17:00:00Z","trend":{"last_30_days":2,"last_60_days":-1,"last_90_days":5}},"risk_score":{"overall_score":85,"risk_level":"Medium","updated_at":"2025-09-15T17:00:00Z","risk_breakdown":{"severe":2,"high":5,"medium":12,"low":8}},"frameworks":[{"framework_id":"soc2","framework_name":"SOC 2","compliance_score":8.2,"score_label":"Healthy","updated_at":"2025-09-15T17:00:00Z","compliance_breakdown":{"compliant":20,"in_review":20,"not_applicable":10,"not_assessed":20,"not_compliant":10,"partially_compliant":10,"compliance_achieved_percentage":20,"total":100},"assessment_breakdown":{"yes":15,"no":15,"partially":20,"not_answered":40,"not_applicable":10,"answering_percentage":90,"total":100}}],"work_progress":{"evidence":{"completed":45,"review":10,"in_progress":25,"not_started":20,"not_applicable":0,"completion_percentage":45,"total":100},"updated_at":"2025-09-15T17:00:00Z"}}}}}}},"400":{"description":"Bad Request — Invalid input or business rule violation.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"validationError":{"summary":"Multiple validation or business logic errors","description":"Indicates that one or more request parameters are invalid or violates business validation rules. The client must correct the request and retry.","value":{"errors":[{"code":"VALIDATION_ERROR","title":"Invalid Request Parameter","detail":"One or more query parameters are invalid. Ensure all filters and fields follow the supported format."}]}}}}}},"401":{"description":"Unauthorized - Authentication required","content":{"application/json":{"examples":{"ErrorResponse":{"description":"Returned when authentication fails due to a missing, invalid, or expired Bearer access token.","value":{"errors":[{"code":"UNAUTHORIZED","title":"Invalid or expired token.","detail":"The provided JWT is invalid or has expired. Please authenticate again and include a valid Bearer token."}]}}}}}},"404":{"description":"Not Found — Client not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"ClientNotFound":{"summary":"Client not found","description":"The requested client or tenant was not found, or the API path/version is invalid or unsupported.","value":{"errors":[{"code":"NOT_FOUND","title":"Client Not Found","detail":"No client was found for client_id '65bcf1e-a26b-4abc-ad9a-8607e2f43910'."}]}}}}}},"500":{"description":"Internal server error","content":{"application/json":{"examples":{"ErrorResponse":{"description":"Represents a generic server failure. The client request was valid, but processing failed due to an internal system error.","value":{"errors":[{"code":"INTERNAL_SERVER_ERROR","title":"Internal server error.","detail":"An unexpected error occurred on the server. Please try again later."}]}}}}}}},"security":[{"apiKey":[]}]}},"/controlmap/v1/clients/{client_id}/risks/{risk_id}":{"get":{"tags":["Risks"],"summary":"Get Client Risk","description":"Retrieves detailed information about a specific risk using its unique identifier.","operationId":"02_ClientRisk","parameters":[{"name":"client_id","in":"path","description":"Unique identifier of the client","required":true,"schema":{"type":"string"},"example":"365bcf1e-a26b-4abc-ad9a-8607e2f43910"},{"name":"risk_id","in":"path","description":"Unique identifier of the risk to retrieve","required":true,"schema":{"type":"integer"},"example":1001}],"responses":{"200":{"description":"Successfully retrieved the risk details","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RiskResponse"},"examples":{"RiskResponse":{"description":"RiskResponse","value":{"id":1,"code":"RSK-1","name":"Phishing","description":"Risk of data theft, account takeover, fraudulent transactions on behalf of your company employees","owner":{"id":1,"name":"Joel King"},"status":"Assessment in progress","department":"Sales","risk_category":"Asset Management","treatment":"Avoid","business_impact":"Phishing risk refers to the threat of attackers deceiving employees or users into revealing sensitive information such as login credentials, financial data, or confidential business information through fraudulent emails, messages, or websites.","created_by":{"id":1,"name":"Joel King"},"inherent_risk_score":20,"inherent_risk_label":"Severe","current_risk_score":20,"current_risk_label":"Severe","target_risk_score":1,"target_risk_label":"Low","created_at":"2027-01-30T15:28:17.354Z","updated_at":"2027-01-30T15:28:17.354Z"}}}}}},"400":{"description":"Required Parameter Missing","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"ErrorResponse":{"description":"Indicates that one or more request parameters are invalid or violates business validation rules. The client must correct the request and retry.","value":{"errors":[{"code":"INVALID_CLIENT","title":"Invalid client identifier.","detail":"The clientId 'leno13' is invalid or not registered. Please verify the client ID in the request path."}]}}}}}},"401":{"description":"Unauthorized - Authentication required","content":{"application/json":{"examples":{"ErrorResponse":{"description":"Returned when authentication fails due to a missing, invalid, or expired Bearer access token.","value":{"errors":[{"code":"UNAUTHORIZED","title":"Invalid or expired token.","detail":"The provided JWT is invalid or has expired. Please authenticate again and include a valid Bearer token."}]}}}}}},"404":{"description":"Risk not found with the specified ID","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"NotFoundError":{"description":"The system was unable to locate the specified client or tenant, or no risk exists for the provided risk ID.","value":{"errors":[{"code":"NOT_FOUND","title":"Not_Found","detail":"Risk not found with id: 1"}]}}}}}},"500":{"description":"Internal server error","content":{"application/json":{"examples":{"ErrorResponse":{"description":"Represents a generic server failure. The client request was valid, but processing failed due to an internal system error.","value":{"errors":[{"code":"INTERNAL_SERVER_ERROR","title":"Internal server error.","detail":"An unexpected error occurred on the server. Please try again later."}]}}}}}}},"security":[{"apiKey":[]}]}},"/controlmap/v1/clients/evidences-summary":{"get":{"tags":["Evidences"],"summary":"List Clients Evidence Summaries","description":"Returns paginated evidence summaries for all partner clients.\n\nThis endpoint supports:\n- Cursor-based pagination\n- Sorting\n- Filtering\n\n**Use Cases:**\n- Retrieve evidence summaries across all MSP clients\n- Build partner-level dashboards\n- Analyze evidence completeness across multiple tenants\n- Paginate large evidence summary datasets\n","operationId":"02_evidenceApi","parameters":[{"name":"filter[client.id]","in":"query","description":"Filters evidence summaries by `client.id`.\n\n**Supported operators:**\n- `eq`\n- `in`\n\n**Examples:**\n- `filter[client.id]=0bd019eb-8114-45d5-945d-c3a65dee` — to filter for exact match\n- `filter[client.id]=eq:0bd019eb-8114-45d5-945d-c3a65dee` — to filter for exact match\n- `filter[client.id]=in:0bd019eb-8114-45d5-945d-c3a65dee` —to filter for any match in list\n","schema":{"type":"string"},"example":"eq:0bd019eb-8114-45d5-945d-c3a65dee"},{"name":"filter[client.tenant_id]","in":"query","description":"Filters evidence summaries by `client.tenant_id`.\n\n**Examples:**\n- `filter[client.tenant_id]=scal1` — to filter for exact match\n- `filter[client.tenant_id]=eq:scal1` — to filter for exact match\n- `filter[client.tenant_id]=in:scal1,cont2,mont` —to filter for any match in list\n","schema":{"type":"string"},"example":"eq:scal1"},{"name":"filter[client.name]","in":"query","description":"Filters evidence summaries by `client.name`.\n\n**Examples:**\n- `filter[client.name]=Joel Tech` — to filter for exact match\n- `filter[client.name]=eq:Joel Tech` — to filter for exact match\n- `filter[client.name]=in:Joel Tech,Dan Tech` —to filter for any match in list\n","schema":{"type":"string"},"example":"eq:Client_Abc"},{"name":"page_size","in":"query","description":"Number of records per page (default 50, maximum 200).","required":false,"schema":{"type":"integer","default":50,"maximum":200,"minimum":1}},{"name":"cursor","in":"query","description":"Opaque Base64-encoded pagination cursor for fetching the next page.","required":false,"schema":{"type":"string","pattern":"^[A-Za-z0-9+/=]*$"}},{"name":"sort","in":"query","description":"Sort evidence summaries by a single field.\n\n**Format:**\n- `field` or `+field`: ascending\n- `-field`: descending\n\n**Allowed fields:**\n- `client.tenant_id`\n- `client.name`\n\n**Examples:**\n- `sort=client.tenant_id`\n- `sort=+client.tenant_id`\n- `sort=-client.name`\n","required":false,"schema":{"type":"string","pattern":"^[+-]?(client.tenant_id|client.name)$"},"example":"-client.tenant_id"}],"responses":{"200":{"description":"Ok","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ClientEvidencePaginatedResponse"},"examples":{"SuccessResponse":{"summary":"Example successful response","description":"Shows aggregated Evidence summary across clients with pagination.","value":{"data":[{"client":{"id":"365bcf1e-a26b-4abc-ad9a-8607e2f43910","name":"Joel Tech","tenant_id":"joel1"},"evidence_summary":{"completed":82,"review":0,"in_progress":0,"not_started":2,"not_applicable":0,"total":84,"completion_percentage":97.6}},{"client":{"id":"365bcf1e-a26b-4abc-ad9a-8607e2f43911","name":"Vistel Tech","tenant_id":"joel2"},"evidence_summary":{"completed":1,"review":0,"in_progress":1,"not_started":128,"not_applicable":0,"total":130,"completion_percentage":0.8}}],"total_count":2,"next_cursor":"eyJpZCI6NDQxLCJwYWdlIjoyfQ=="}}}}}},"400":{"description":"Bad Request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"validationError":{"summary":"Invalid query parameter or operator","description":"Returned when the request contains an invalid filter parameter or an unsupported query operator.","value":{"errors":[{"code":"VALIDATION_ERROR","title":"Invalid Query Parameter","detail":"Invalid filter or unsupported operator."}]}},"invalidSortField":{"summary":"Invalid sort field","description":"Returned when the request contains an invalid or unsupported sort parameter. The client must provide a valid sort field.","value":{"errors":[{"code":"BAD_REQUEST","title":"Validation error.","detail":"Allowed fields:client.tenant_id, client.name. Use '-' for descending, '+' or no prefix for ascending."}]}},"invalidFilterField":{"summary":"Invalid filter field","description":"Returned when the request includes an unsupported or invalid filter field. The client must use a valid, filterable field.","value":{"errors":[{"code":"BAD_REQUEST","title":"Invalid Filter","detail":"Filtering is not supported for the field 'abc'. Please use a valid filterable field."}]}}}}}},"500":{"description":"Internal Server Error","content":{"application/json":{"examples":{"ErrorResponse":{"description":"Represents a generic server failure. The client request was valid, but processing failed due to an internal system error.","value":{"errors":[{"code":"INTERNAL_SERVER_ERROR","title":"Internal server error.","detail":"An unexpected error occurred on the server. Please try again later."}]}}}}}}},"security":[{"apiKey":[]}]}},"/controlmap/v1/clients/{client_id}/frameworks/{framework_id}/objectives/{objective_id}":{"get":{"tags":["Frameworks"],"summary":"Get Client Objective","description":"Returns a single objective for the specified client and framework.","operationId":"02_getClientObjectiveById","parameters":[{"name":"client_id","in":"path","description":"Unique identifier of the client whose objective is being retrieved.","required":true,"schema":{"type":"string"},"example":"365bcf1e-a26b-4abc-ad9a-8607e2f43910"},{"name":"framework_id","in":"path","description":"Unique identifier of the framework that contains the objective.","required":true,"schema":{"type":"integer","format":"int32"},"example":3},{"name":"objective_id","in":"path","description":"Unique identifier of the objective to retrieve.","required":true,"schema":{"type":"integer","format":"int32"},"example":279}],"responses":{"200":{"description":"Objective retrieved successfully.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ObjectiveDetail"},"examples":{"SuccessResponse":{"description":"Successful response containing detailed information of a specific objective.","value":{"id":393,"code":"4.1","name":"Understanding the organization and its context","description":"<p>The organization shall determine external and internal issues that are relevant to its purpose and that affect its ability to achieve the intended outcome(s) of its information security management system. NOTE Determining these issues refers to establishing the external and internal context of the organization considered in Clause 5.3 of ISO 31000:2009[5].</p>","status":"Compliant","level1_code":"4","level1_name":"Context of the organisation","level2_code":"4.1","level2_name":"Understanding the organization and its context","created_at":"2025-09-16T05:45:01","updated_at":"2026-04-07T05:49:20","in_scope":true,"type":"clauses","implementation_details":"<p>This is demo implementation data for testing purposes.</p>","automated_test":"Failing","automated_tested_on":"2026-04-07T06:53:25","current_maturity":{"id":40180,"name":"Initial","description":"The process, function or capability is generally documented and is applied by individuals on a case-by-case basis. The practices are informally adopted, tracked, and reported on by the business.","score":1},"target_maturity":{"id":40183,"name":"Optimizing","description":"The process is continuously improved to meet relevant current and projected enterprise goals.","score":4},"assessment_questions":[{"id":14,"code":"Q-GOV-08","title":"Does the organization define the context of its business model and document the mission of the organization?","answer":"Yes"}],"audit_tests":[{"audit_name":"Audit-test-1","evidence_requests":[{"id":115,"code":"ER-115","title":"Understanding the organization and its context","audit_result":"Meets with exceptions","detailed_evaluation":{"design_and_implementation":"Acceptable with recommendations","operational_status":"Functional with exceptions","quality_of_evidence":"Partially adequate","findings":"fghgfhgf"}}]},{"audit_name":"Audit-test-2","evidence_requests":[{"id":1949,"code":"ER-115","title":"Understanding the organization and its context","audit_result":"Meets with exceptions","detailed_evaluation":{"design_and_implementation":"Acceptable with recommendations","operational_status":"Functional with exceptions","quality_of_evidence":"Partially adequate","findings":"Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum"}}]}],"controls":[{"id":112,"name":"<p>Senior management regularly reviews the development of the security program and aligns the &nbsp;Objectives, Requirements, and Parties to its products, services, and other internal and external factors affecting the company activities.</p>","code":"GOV-11"}],"documents":[{"id":32,"name":" Information Security Context Requirements and Scope","code":"GOV-1"},{"id":34,"name":"Information Security Objectives & Plan ","code":"GOV-3"}],"evidences":[{"id":109,"name":"Up-to-date registry of regulatory, statutory, and contractual requirements.","code":"EV-11"},{"id":110,"name":"Most recently completed risk assessment ","code":"EV-12"}],"action_items":[{"id":217,"name":"Not Performed: Does the organization adequately train contingency personnel and applicable stakeholders in their contingency roles and responsibilities?","code":"AI-1"}],"risks":[],"responsible_party":[{"id":1961,"name":"Responsible Party 1","responsibility":"Demo responsibility for Party 1","party_name":"Responsible Party 1"},{"id":1962,"name":"Responsible Party 2","responsibility":"Demo responsibility for Party 2","party_name":"Responsible Party 2"},{"id":1963,"name":"Responsible Party 3","responsibility":"Demo responsibility for Party 3","party_name":"Responsible Party 3"},{"id":1964,"name":"Responsible Party 4","responsibility":"Demo responsibility for Party 4","party_name":"Responsible Party 4"},{"id":1965,"name":"Responsible Party 5","responsibility":"Demo responsibility for Party 5","party_name":"Responsible Party 5"}],"cross_walks":[{"id":1255,"code":"ID.SC","name":"Supply Chain Risk Management","program_name":"NIST CSF"}]}}}}}},"401":{"description":"Unauthorized - Authentication required","content":{"application/json":{"examples":{"ErrorResponse":{"description":"Returned when authentication fails due to a missing, invalid, or expired Bearer access token.","value":{"errors":[{"code":"UNAUTHORIZED","title":"Invalid or expired token.","detail":"The provided JWT is invalid or has expired. Please authenticate again and include a valid Bearer token."}]}}}}}},"404":{"description":"Objective or framework not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"ErrorResponse":{"description":"Returned when the requested objective or framework is not found.","value":{"errors":[{"code":"NOT_FOUND","title":"Resource Not Found","detail":"The requested objective could not be found for the specified framework."}]}}}}}},"500":{"description":"Internal Server Error","content":{"application/json":{"examples":{"ErrorResponse":{"description":"Represents a generic server failure. The client request was valid, but processing failed due to an internal system error.","value":{"errors":[{"code":"INTERNAL_SERVER_ERROR","title":"Internal server error.","detail":"An unexpected error occurred on the server. Please try again later."}]}}}}}}},"security":[{"apiKey":[]}]}},"/controlmap/v1/clients/{client_id}/evidences":{"post":{"tags":["Evidences"],"summary":"Create Client Evidence","description":"   Creates a new evidence with all necessary details.\n","operationId":"03_evidenceApi","parameters":[{"name":"client_id","in":"path","description":"Unique identifier for the client (ControlMap tenant or client ID).","required":true,"schema":{"type":"string","format":"uuid","example":"365bcf1e-a26b-4abc-ad9a-8607e2f43910"}}],"requestBody":{"description":"Request payload containing fields required to create a new evidence.\nThis includes evidence metadata, ownership information, schedule configuration.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateEvidenceRequest"},"examples":{"CreateEvidenceExample":{"summary":"Sample request body for creating evidence","description":"CreateEvidenceExample","value":{"title":"SOC 2 Access Review Evidence","description":"Quarterly user access review evidence for SOC 2 audit.","owner_email":"joel@example.com","assignee_email":"joel@example.com","repeat_type":"recurring","schedule":{"frequency":"weekly","interval":2,"days":["monday","tuesday","wednesday"],"start_date":"2025-12-16","end_type":"on_date","end_date":"2026-01-16"}}}}}},"required":true},"responses":{"201":{"description":"Ok","content":{"application/json":{"schema":{"type":"string"},"examples":{"SuccessResponse":{"description":"Identifiers of the created Evidence and Evidence Request.","value":{"id":101,"evidence_request_id":1001}}}}}},"400":{"description":"Bad Request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"validationError":{"summary":"Multiple validation or business logic errors","description":"Example of common validation and business logic failures","value":{"errors":[{"code":"INVALID_CLIENT","title":"Invalid client identifier.","detail":"The clientId '365bcf1e-a26b-4abc-ad9a-8607e2f43910' is invalid or not registered. Please verify the client ID in the request path."},{"code":"VALIDATION_ERROR","title":"Invalid Request Parameter","detail":"title: Evidence title is required"},{"code":"VALIDATION_ERROR","title":"Invalid Request Parameter","detail":"repeatType: Repeat Type must be once or recurring"},{"code":"VALIDATION_ERROR","title":"Invalid Request","detail":"Schedule details are required when repeat_type is RECURRING"},{"code":"VALIDATION_ERROR","title":"Invalid Request Parameter","detail":"schedule.interval: Repeat interval must be at least 1"},{"code":"VALIDATION_ERROR","title":"Invalid Request Parameter","detail":"schedule.daysOfWeek[0]: Invalid day name"},{"code":"VALIDATION_ERROR","title":"Invalid Request Parameter","detail":"schedule.endType: End type must be on_date, or after_occurrences"},{"code":"VALIDATION_ERROR","title":"Invalid Request Parameter","detail":"schedule.startDate: Start date is required"},{"code":"VALIDATION_ERROR","title":"Invalid Request Parameter","detail":"schedule.frequency: Frequency must be weekly, monthly, or yearly"},{"code":"VALIDATION_ERROR","title":"Invalid Request Parameter","detail":"schedule.dayOfMonth: Day of month must be between 1 and 31"}]}}}}}},"401":{"description":"Unauthorized","content":{"application/json":{"examples":{"ErrorResponse":{"description":"Returned when authentication fails due to a missing, invalid, or expired Bearer access token.","value":{"errors":[{"code":"UNAUTHORIZED","title":"Invalid or expired token.","detail":"The provided JWT is invalid or has expired. Please authenticate again and include a valid Bearer token."}]}}}}}},"404":{"description":"Not Found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"ErrorResponse":{"description":"The system was unable to locate the specified client or tenant, or no user exists for the provided email ID.","value":{"errors":[{"code":"NOT_FOUND","title":"User Not Found","detail":"The user with email 'john.doe@example.com' could not be found."}]}}}}}},"500":{"description":"Internal Server Error","content":{"application/json":{"examples":{"ErrorResponse":{"description":"Represents a generic server failure. The client request was valid, but processing failed due to an internal system error.","value":{"errors":[{"code":"INTERNAL_SERVER_ERROR","title":"Internal server error.","detail":"An unexpected error occurred on the server. Please try again later."}]}}}}}}},"security":[{"apiKey":[]}]}},"/controlmap/v1/clients/risks-summary":{"get":{"tags":["Risks"],"summary":"List Clients Risk Summaries","description":"Returns paginated risk summaries for all partner clients.\n\nThis endpoint supports:\n- Advanced field-level filtering using comparison operators (`eq`, `in`)\n- Cursor-based pagination for efficient navigation of large datasets\n- Selective field projection to reduce response payload size\n- Multi-field sorting with ascending/descending order indicators\n\nUse this API to obtain aggregated or filtered risk summaries across clients.\n","operationId":"03_listClientsRiskSummary","parameters":[{"name":"filter[client.tenant_id]","in":"query","description":"Filters records by the `client.tenant_id` field.\n\n**Supported operators:**\n- `eq` — exact match\n- `in` — list-based match\n\n**Examples:**\n- `filter[client.tenant_id]=Joel Tech` — to filter for exact match\n- `filter[client.tenant_id]=eq:Joel Tech` — to filter for exact match\n- `filter[client.tenant_id]=in:Joel Tech,John Tech` — to filter for any match in list\n","schema":{"type":"string"},"example":"eq:Joel Tech"},{"name":"filter[client.name]","in":"query","description":"Filters records by the `client.name` field.\n\n**Supported operators:**\n- `eq` — exact match\n- `in` — list-based match\n\n**Examples:**\n- `filter[client.name]=Joel King` — to filter for exact match\n- `filter[client.name]=eq:Joel King` — to filter for exact match\n- `filter[client.name]=in:Joel King,John` — to filter for any match in list\n","schema":{"type":"string"},"example":"eq:Joel King"},{"name":"page_size","in":"query","description":"Number of records to return per page.\nMust be between **1 and 200**.\nDefault: **50**\n","required":false,"schema":{"type":"integer","format":"int32","default":50,"maximum":200,"minimum":1},"example":50},{"name":"cursor","in":"query","description":"Base64-encoded cursor value used for pagination.\nPass the cursor received from the previous response to fetch the next page.\n","required":false,"schema":{"type":"string","pattern":"^[A-Za-z0-9+/=]*$"},"example":"eyJpZCI6NDQxLCJwYWdlIjoxfQ=="},{"name":"sort","in":"query","description":"One or more sortable fields, separated by commas.\nPrefix with `+` for ascending or `-` for descending.\n\n**Available values:** `client.name`, `client.tenant_id`\n","required":false,"schema":{"type":"string","pattern":"^(?:[+-]|\\s)?(client.tenant_id|client.name)$"},"example":"+client.name,-client.tenant_id"}],"responses":{"200":{"description":"Risk summary retrieved successfully.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ClientRiskPaginatedResponse"},"examples":{"SuccessfulRiskList":{"summary":"Example successful response","description":"Shows aggregated Risk summary across clients with pagination.","value":{"data":[{"client":{"id":"365bcf1e-a26b-4abc-ad9a-8607e2f43910","name":"Joel Tech","tenant_id":"joel1"},"risk_summary":{"overall_score":16,"risk_level":"Severe","updated_at":"2026-02-25T13:19:53","risk_breakdown":{"severe":3,"high":5,"medium":2,"low":0}}},{"client":{"id":"365bcf1e-a26b-4abc-ad9a-8607e2f43911","name":"Vistel Tech","tenant_id":"joel2"},"risk_summary":{"overall_score":12,"risk_level":"High","updated_at":"2026-02-25T13:19:53","risk_breakdown":{"severe":5,"high":8,"medium":3,"low":0}}}],"total_count":2,"next_cursor":"eyJpZCI6NDQxLCJwYWdlIjoyfQ=="}}}}}},"400":{"description":"Invalid request parameters (e.g., invalid cursor or invalid page size).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"InvalidQueryExample":{"summary":"Example of malformed query parameter error","description":"Indicates that one or more request parameters are invalid or violates business validation rules. The client must correct the request and retry.","value":{"errors":[{"code":"VALIDATION_ERROR","title":"Invalid Query Parameter","detail":"The 'cursor' parameter must be a valid Base64-encoded string."}]}}}}}},"401":{"description":"Unauthorized - Authentication required","content":{"application/json":{"examples":{"ErrorResponse":{"description":"Returned when authentication fails due to a missing, invalid, or expired Bearer access token.","value":{"errors":[{"code":"UNAUTHORIZED","title":"Invalid or expired token.","detail":"The provided JWT is invalid or has expired. Please authenticate again and include a valid Bearer token."}]}}}}}},"404":{"description":"Resource Not Found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"Resource Not Found Error":{"description":"The requested client or tenant was not found, or the API path/version is invalid or unsupported.","value":{"errors":[{"code":"NOT_FOUND","title":"Resource Not Found","detail":"The requested resource could not be found. Please verify the API path and version."}]}}}}}},"500":{"description":"Internal server error","content":{"application/json":{"examples":{"ErrorResponse":{"description":"Represents a generic server failure. The client request was valid, but processing failed due to an internal system error.","value":{"errors":[{"code":"INTERNAL_SERVER_ERROR","title":"Internal server error.","detail":"An unexpected error occurred on the server. Please try again later."}]}}}}}}},"security":[{"apiKey":[]}]}},"/controlmap/v1/clients/{client_id}/evidences/{evidence_id}":{"delete":{"tags":["Evidences"],"summary":"Delete Client Evidence","description":"Deletes an evidence that is no longer required for compliance or business purposes.\n","operationId":"06_evidenceApi","parameters":[{"name":"client_id","in":"path","description":"Unique identifier for the client (ControlMap tenant or client ID).","required":true,"schema":{"type":"string","format":"uuid","example":"365bcf1e-a26b-4abc-ad9a-8607e2f43910"}},{"name":"evidence_id","in":"path","description":"ID of the evidence.","required":true,"schema":{"type":"integer","example":101}}],"responses":{"204":{"description":"No Content"},"400":{"description":"Bad Request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"ValidationErrorExample":{"summary":"Invalid deletion request","description":"Indicates that one or more request parameters are invalid or violates business validation rules. The client must correct the request and retry.","value":{"errors":[{"code":"INVALID_CLIENT","title":"Invalid client identifier.","detail":"The clientId '365bcf1e-a26b-4abc-ad9a-8607e2f43910' is invalid or not registered. Please verify the client ID in the request path."}]}}}}}},"401":{"description":"Unauthorized","content":{"application/json":{"examples":{"ErrorResponse":{"description":"Returned when authentication fails due to a missing, invalid, or expired Bearer access token.","value":{"errors":[{"code":"UNAUTHORIZED","title":"Invalid or expired token.","detail":"The provided JWT is invalid or has expired. Please authenticate again and include a valid Bearer token."}]}}}}}},"404":{"description":"Not Found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"ErrorResponse":{"description":"The system was unable to locate the specified client or tenant, or no evidence exists for the provided ID.","value":{"errors":[{"code":"NOT_FOUND","title":"Evidence not found","detail":"No evidence exists with ID '101'."}]}}}}}},"500":{"description":"Internal Server Error","content":{"application/json":{"examples":{"ErrorResponse":{"description":"Represents a generic server failure. The client request was valid, but processing failed due to an internal system error.","value":{"errors":[{"code":"INTERNAL_SERVER_ERROR","title":"Internal server error.","detail":"An unexpected error occurred on the server. Please try again later."}]}}}}}}},"security":[{"apiKey":[]}]},"patch":{"tags":["Evidences"],"summary":"Update Client Evidence","description":"Partially updates an existing evidence for the specified client.\n\nThis operation allows updating one or more evidence fields, including:\n- **`Name`**\n\n- **`Description`**\n\n- **`Owner`**\n\n- **`Schedule`**\n\nOnly the fields provided in the request payload will be updated.\nAll other fields will remain unchanged.\n---\n\n **Important — Schedule Rules**\n\n- An evidence can have **only one schedule**.\n- This endpoint **does not allow updating an existing schedule**.\n- If a schedule already exists, the request will be **rejected**.\n- To change the schedule, the existing schedule must be **deleted first** using the **Delete Schedule API**.\n- If no schedule exists, this endpoint will **create a new schedule**.\n","operationId":"04_evidenceApi","parameters":[{"name":"client_id","in":"path","description":"Unique identifier for the client (ControlMap tenant or client ID).","required":true,"schema":{"type":"string","format":"uuid","example":"365bcf1e-a26b-4abc-ad9a-8607e2f43910"}},{"name":"evidence_id","in":"path","description":"ID of the evidence.","required":true,"schema":{"type":"integer","example":101}}],"requestBody":{"description":"Payload containing the fields to update within the evidence record.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidencePartialUpdate"},"examples":{"EvidencePartialUpdateExample":{"description":"Example request body for updating evidence","value":{"title":"SOC 2 Access Review Evidence (Revised)","description":"Updated description after reviewer requested additional clarification.","owner":"joel@example.com","schedule":{"frequency":"WEEKLY","interval":1,"days_of_week":["MONDAY","FRIDAY"],"start_date":"2025-11-01","end_type":"after_occurrences","occurrences":4}}}}}},"required":true},"responses":{"204":{"description":"No Content"},"400":{"description":"Bad Request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"validationError":{"summary":"Multiple validation or business logic errors","description":"Example of common validation and business logic failures","value":{"errors":[{"code":"INVALID_CLIENT","title":"Invalid client identifier.","detail":"The clientId '365bcf1e-a26b-4abc-ad9a-8607e2f43910' is invalid or not registered. Please verify the client ID in the request path."},{"code":"BAD_REQUEST","title":"Failed to read request","detail":"The request body is invalid or malformed. Please ensure the JSON format is correct, and required fields are provided."},{"code":"VALIDATION_ERROR","title":"Invalid Request","detail":"Evidence title is required and must not be null."},{"code":"VALIDATION_ERROR","title":"Invalid Request","detail":"Evidence owner is required and must not be null or empty."},{"code":"VALIDATION_ERROR","title":"Invalid owner email","detail":"No user exists with email 'joel@example.com'."},{"code":"VALIDATION_ERROR","title":"Invalid schedule configuration","detail":"schedule.frequency: Frequency is required."},{"code":"VALIDATION_ERROR","title":"Invalid Request Parameter","detail":"schedule.startDate: Start date is required"},{"code":"VALIDATION_ERROR","title":"Invalid schedule configuration","detail":"End date is required."},{"code":"VALIDATION_ERROR","title":"Invalid Request Parameter","detail":"schedule.daysOfWeek[0]: Invalid day name"}]}}}}}},"401":{"description":"Unauthorized","content":{"application/json":{"examples":{"ErrorResponse":{"description":"Returned when authentication fails due to a missing, invalid, or expired Bearer access token.","value":{"errors":[{"code":"UNAUTHORIZED","title":"Invalid or expired token.","detail":"The provided JWT is invalid or has expired. Please authenticate again and include a valid Bearer token."}]}}}}}},"404":{"description":"Not Found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"ErrorResponse":{"description":"The system was unable to locate the specified client or tenant, or no evidence exists for the provided ID.","value":{"errors":[{"code":"NOT_FOUND","title":"Evidence not found","detail":"No evidence exists with ID '101'."}]}}}}}},"409":{"description":"Conflict","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"ScheduleAlreadyExists":{"summary":"Schedule already exists","description":"Returned when attempting to create a new schedule for an evidence that already has an active schedule.","value":{"errors":[{"code":"SCHEDULE_ALREADY_EXISTS","title":"Schedule already exists","detail":"An evidence schedule already exists. Delete the existing schedule before creating a new one."}]}}}}}},"500":{"description":"Internal Server Error","content":{"application/json":{"examples":{"ErrorResponse":{"description":"Represents a generic server failure. The client request was valid, but processing failed due to an internal system error.","value":{"errors":[{"code":"INTERNAL_SERVER_ERROR","title":"Internal server error.","detail":"An unexpected error occurred on the server. Please try again later."}]}}}}}}},"security":[{"apiKey":[]}]}},"/controlmap/v1/clients/{client_id}/evidences/{evidence_id}/schedule":{"delete":{"tags":["Evidences"],"summary":"Delete Evidence Refresh Schedule","description":"Deletes the refresh schedule associated with an existing evidence record.\n\nThis operation removes **only the schedule configuration** and does not delete\nthe evidence itself.\n\n---\n\n **Important — Confirmation Required**\n\nIf a refresh schedule already exists, deleting it requires **explicit confirmation**\nfrom the client. This ensures that related evidence requests are handled correctly.\n\nThe client must specify **one** of the following options when deleting a schedule:\n\n- **`Disable future evidence requests`**\n  — Disables all upcoming evidence requests generated by the refresh schedule.\n\n- **`Disable future evidence requests and delete existing requests`**\n  — Disables all future evidence requests and deletes existing incomplete requests.\n\nIf confirmation is not provided, the request will be rejected.\n","operationId":"05_evidenceApi","parameters":[{"name":"client_id","in":"path","description":"Unique identifier for the client (ControlMap tenant or client ID).","required":true,"schema":{"type":"string","format":"uuid","example":"365bcf1e-a26b-4abc-ad9a-8607e2f43910"}},{"name":"evidence_id","in":"path","description":"ID of the evidence to delete schedule.","required":true,"schema":{"type":"integer","example":101}},{"name":"schedule_action","in":"query","description":"Specifies how evidence requests are handled when deleting a refresh schedule.","required":true,"schema":{"type":"string","enum":["Disable future evidence requests","Disable future evidence requests and delete existing requests"],"example":"Disable future evidence requests"}}],"responses":{"204":{"description":"No Content"},"400":{"description":"Bad Request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"InvalidClientId":{"summary":"Invalid client identifier","description":"Returned when the provided clientId is invalid or not recognized.","value":{"errors":[{"code":"INVALID_CLIENT","title":"Invalid client identifier.","detail":"The clientId '365bcf1e-a26b-4abc-ad9a-8607e2f43910' is invalid or not registered. Please verify the client ID in the request path."}]}},"InvalidScheduleAction":{"summary":"Invalid schedule action value","description":"Returned when the provided schedule_action value is not supported. The client must provide one of the allowed values.","value":{"errors":[{"code":"VALIDATION_ERROR","title":"Invalid request parameter.","detail":"schedule_action must be one of: Disable future evidence requests, Disable future evidence requests and delete existing requests."}]}}}}}},"401":{"description":"Unauthorized","content":{"application/json":{"examples":{"ErrorResponse":{"description":"Returned when authentication fails due to a missing, invalid, or expired Bearer access token.","value":{"errors":[{"code":"UNAUTHORIZED","title":"Invalid or expired token.","detail":"The provided JWT is invalid or has expired. Please authenticate again and include a valid Bearer token."}]}}}}}},"404":{"description":"Not Found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"ErrorResponse":{"description":"The system was unable to locate the specified client or tenant, or no evidence exists for the provided ID.","value":{"errors":[{"code":"NOT_FOUND","title":"Evidence not found","detail":"No evidence exists with ID '101'."}]}}}}}},"500":{"description":"Internal Server Error","content":{"application/json":{"examples":{"ErrorResponse":{"description":"Represents a generic server failure. The client request was valid, but processing failed due to an internal system error.","value":{"errors":[{"code":"INTERNAL_SERVER_ERROR","title":"Internal server error.","detail":"An unexpected error occurred on the server. Please try again later."}]}}}}}}},"security":[{"apiKey":[]}]}},"/controlmap/v1/clients/{client_id}/evidences/{evidence_id}/requests":{"get":{"tags":["Evidences"],"summary":"List Evidence Requests","description":"Retrieves all evidence requests and it's document associated with a specific evidence record.\n\nThis is typically used when:\n- Viewing the request history for an evidence\n- Auditing evidence review workflow\n- Displaying evidence request details for the client or reviewer\n","operationId":"07_evidenceApi","parameters":[{"name":"client_id","in":"path","description":"Unique identifier for the client (ControlMap tenant or client ID).","required":true,"schema":{"type":"string","format":"uuid","example":"365bcf1e-a26b-4abc-ad9a-8607e2f43910"}},{"name":"evidence_id","in":"path","description":"ID of the evidence.","required":true,"schema":{"type":"integer","example":101}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceResponse"},"examples":{"ClientEvidenceRequestResponse":{"description":"Example response containing multiple evidence requests.","value":{"client":{"id":"365bcf1e-a26b-4abc-ad9a-8607e2f43910","name":"Joel Tech","tenant_id":"joel1"},"evidence_id":2,"data":[{"id":1,"code":"EV-2-1","status":"Completed","created_by":{"id":24337,"name":"Joel King"},"owner":{"id":24337,"name":"Joel King"},"documents":[],"due_date":"2025-11-20","updated_at":"2025-11-20T11:38:34","created_at":"2025-07-17T13:55:56","implementation_notes":null},{"id":2,"code":"EV-2-2","status":"In Progress","created_by":{"id":24337,"name":"Joel King"},"owner":{"id":24337,"name":"Joel King"},"documents":[{"id":1,"file_name":"Backup_Restoration_Test_Report.pdf"},{"id":2,"file_name":"Restore_Test_Evidence.png"}],"due_date":"2022-12-31T18:30:00","updated_at":"2026-02-11T08:40:16","created_at":"2026-02-06T12:03:17","implementation_notes":"Restoration test completed successfully, data integrity verified"}]}}}}}},"400":{"description":"Bad Request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"badRequest":{"summary":"Invalid path or request values","description":"Indicates that one or more request parameters are invalid or violates business validation rules. The client must correct the request and retry.","value":{"errors":[{"code":"INVALID_CLIENT","title":"Invalid client identifier.","detail":"The clientId '365bcf1e-a26b-4abc-ad9a-8607e2f43910' is invalid or not registered. Please verify the client ID in the request path."}]}}}}}},"401":{"description":"Unauthorized","content":{"application/json":{"examples":{"ErrorResponse":{"description":"Returned when authentication fails due to a missing, invalid, or expired Bearer access token.","value":{"errors":[{"code":"UNAUTHORIZED","title":"Invalid or expired token.","detail":"The provided JWT is invalid or has expired. Please authenticate again and include a valid Bearer token."}]}}}}}},"404":{"description":"Not Found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"ErrorResponse":{"description":"The system was unable to locate the specified client or tenant, or no evidence exists for the provided ID.","value":{"errors":[{"code":"NOT_FOUND","title":"Evidence not found","detail":"Requested resource 'Evidence' with ID 101 does not exist."}]}}}}}},"500":{"description":"Internal Server Error","content":{"application/json":{"examples":{"ErrorResponse":{"description":"Represents a generic server failure. The client request was valid, but processing failed due to an internal system error.","value":{"errors":[{"code":"INTERNAL_SERVER_ERROR","title":"Internal server error.","detail":"An unexpected error occurred on the server. Please try again later."}]}}}}}}},"security":[{"apiKey":[]}]},"post":{"tags":["Evidences"],"summary":"Create Request in Evidence","description":"Creates a new request inside an existing evidence.\n\nThis operation is typically used when:\n- Additional clarification or documentation is needed\n- Reviewer initiates an evidence request workflow\n- Evidence must be updated or completed by the client\n\nThe authenticated user is automatically resolved and stored as the creator\nof the evidence request.\n","operationId":"08_evidenceApi","parameters":[{"name":"client_id","in":"path","description":"Unique identifier for the client (ControlMap tenant or client ID).","required":true,"schema":{"type":"string","format":"uuid","example":"365bcf1e-a26b-4abc-ad9a-8607e2f43910"}},{"name":"evidence_id","in":"path","description":"ID of the evidence.","required":true,"schema":{"type":"integer","example":101}}],"responses":{"201":{"description":"Ok","content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceResponse"},"example":{"id":101}}}},"400":{"description":"Bad Request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"validationError":{"summary":"Multiple validation or business logic errors","description":"Example of common validation and business logic failures","value":{"errors":[{"code":"INVALID_CLIENT","title":"Invalid client identifier.","detail":"The clientId '365bcf1e-a26b-4abc-ad9a-8607e2f43910' is invalid or not registered. Please verify the client ID in the request path."},{"code":"VALIDATION_ERROR","title":"Invalid Request Parameter","detail":"One or more query parameters are invalid."}]}}}}}},"401":{"description":"Unauthorized","content":{"application/json":{"examples":{"ErrorResponse":{"description":"Returned when authentication fails due to a missing, invalid, or expired Bearer access token.","value":{"errors":[{"code":"UNAUTHORIZED","title":"Invalid or expired token.","detail":"The provided JWT is invalid or has expired. Please authenticate again and include a valid Bearer token."}]}}}}}},"404":{"description":"Not Found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"ErrorResponse":{"description":"ErrorResponse","value":{"errors":[{"code":"NOT_FOUND","title":"Evidence not found","detail":"Requested resource 'Evidence' with ID 897 does not exist."}]}}}}}},"500":{"description":"Internal Server Error","content":{"application/json":{"examples":{"ErrorResponse":{"description":"Represents a generic server failure. The client request was valid, but processing failed due to an internal system error.","value":{"errors":[{"code":"INTERNAL_SERVER_ERROR","title":"Internal server error.","detail":"An unexpected error occurred on the server. Please try again later."}]}}}}}}},"security":[{"apiKey":[]}]}},"/controlmap/v1/clients/{client_id}/evidences/{evidence_id}/documents/signed-url":{"post":{"tags":["Evidences"],"summary":"Create Evidence Request and Generate Signed URLs for Documents","description":"Creates an new evidence request and generates pre-signed URL(s)\nfor uploading document(s) to that evidence request for the specified evidence.\nThe client uploads files directly to S3 using the returned signed Urls and method\nbefore expires_in_seconds elapses.\n","operationId":"09_evidenceApi","parameters":[{"name":"client_id","in":"path","description":"Unique identifier for the client (ControlMap tenant or client ID).","required":true,"schema":{"type":"string","format":"uuid","example":"365bcf1e-a26b-4abc-ad9a-8607e2f43910"}},{"name":"evidence_id","in":"path","description":"ID of the evidence.","required":true,"schema":{"type":"integer","example":101}}],"requestBody":{"description":"List of documents to upload (file name and size in bytes).","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/EvidenceUploadRequest"}},"examples":{"GenerateSignedUrlsRequest":{"summary":"Generate signed URLs for multiple documents","description":"GenerateSignedUrlsRequest","value":[{"file_name":"User_Access_Review_Q1_2026.pd","file_size_bytes":245760},{"file_name":"SSO_Login_Success_2026-02-12.png","file_size_bytes":102400}]}}}},"required":true},"responses":{"201":{"description":"Ok","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SignedUploadResponse"},"examples":{"SignedUploadResponse":{"summary":"Response containing signed URLs for upload","description":"SignedUploadResponse","value":{"evidence_request_id":101,"documents":[{"file_name":"User_Access_Review_Q1_2026.pdf","document_id":501,"method":"PUT","signed_url":"https://s3....","expires_in_seconds":300},{"file_name":"SSO_Login_Success_2026-02-12.png","document_id":502,"method":"PUT","signed_url":"https://s3....","expires_in_seconds":300}]}}}}}},"400":{"description":"Bad Request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"ValidationError":{"summary":"Validation errors","description":"Indicates that one or more request parameters are invalid or violates business validation rules. The client must correct the request and retry.","value":{"errors":[{"code":"VALIDATION_ERROR","title":"Invalid Request Parameter","detail":"File size must be greater than 0"}]}}}}}},"401":{"description":"Unauthorized","content":{"application/json":{"examples":{"ErrorResponse":{"description":"Returned when authentication fails due to a missing, invalid, or expired Bearer access token.","value":{"errors":[{"code":"UNAUTHORIZED","title":"Invalid or expired token.","detail":"The provided JWT is invalid or has expired. Please authenticate again and include a valid Bearer token."}]}}}}}},"404":{"description":"Not Found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"ErrorResponse":{"description":"The system was unable to locate the specified client or tenant, or no evidence request exists for the provided ID.","value":{"errors":[{"code":"NOT_FOUND","title":"Evidence Request Not Found","detail":"No evidence request exists with id '101' for the specified client."}]}}}}}},"500":{"description":"Internal Server Error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"ErrorResponse":{"description":"Represents a generic server failure. The client request was valid, but processing failed due to an internal system error.","value":{"errors":[{"code":"INTERNAL_SERVER_ERROR","title":"Internal server error.","detail":"An unexpected error occurred. Please try again later."}]}}}}}}},"security":[{"apiKey":[]}]}},"/controlmap/v1/clients/{client_id}/evidence-requests/{evidence_request_id}/documents/signed-url":{"post":{"tags":["Evidences"],"summary":"Generate Signed URLs to Upload Documents for an Evidence Request","description":"Generates pre-signed URL to upload document(s) for the specified evidence request.\n\nThe client uploads files directly to S3 using the returned signedUrl and method\nbefore expires_in_seconds elapses.\n","operationId":"09_evidenceApi_1","parameters":[{"name":"client_id","in":"path","description":"Unique identifier for the client (ControlMap tenant or client ID).","required":true,"schema":{"type":"string","format":"uuid","example":"365bcf1e-a26b-4abc-ad9a-8607e2f43910"}},{"name":"evidence_request_id","in":"path","description":"ID of the evidence request.","required":true,"schema":{"type":"integer","example":101}}],"requestBody":{"description":"List of documents to upload (file name and size in bytes).","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/EvidenceUploadRequest"}},"examples":{"GenerateSignedUrlsRequest":{"summary":"Generate signed URLs for multiple documents","description":"Provides a list of documents with their file names and sizes (in bytes) to generate pre-signed upload URLs. These URLs grant temporary, secure access for direct file uploads to storage services, reducing backend load and improving performance for large file transfers.","value":[{"file_name":"User_Access_Review_Q1_2026.pd","file_size_bytes":245760},{"file_name":"SSO_Login_Success_2026-02-12.png","file_size_bytes":102400}]}}}},"required":true},"responses":{"201":{"description":"Ok","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SignedUploadResponse"},"examples":{"SignedUploadResponse":{"summary":"Response containing signed URLs for upload","description":"SignedUploadResponse","value":{"evidence_request_id":101,"evidence_request_code":"EV-7-4","documents":[{"file_name":"User_Access_Review_Q1_2026.pdf","document_id":501,"method":"PUT","signed_url":"https://s3....","expires_in_seconds":300},{"file_name":"SSO_Login_Success_2026-02-12.png","document_id":502,"method":"PUT","signed_url":"https://s3....","expires_in_seconds":300}]}}}}}},"400":{"description":"Bad Request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"ValidationError":{"summary":"Validation errors","description":"Indicates that one or more request parameters are invalid or violates business validation rules. The client must correct the request and retry.","value":{"errors":[{"code":"VALIDATION_ERROR","title":"Invalid Request Parameter","detail":"File size must be greater than 0"}]}}}}}},"401":{"description":"Unauthorized","content":{"application/json":{"examples":{"ErrorResponse":{"description":"Returned when authentication fails due to a missing, invalid, or expired Bearer access token.","value":{"errors":[{"code":"UNAUTHORIZED","title":"Invalid or expired token.","detail":"The provided JWT is invalid or has expired. Please authenticate again and include a valid Bearer token."}]}}}}}},"404":{"description":"Not Found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"ErrorResponse":{"description":"The system was unable to locate the specified client or tenant, or no evidence request exists for the provided ID.","value":{"errors":[{"code":"NOT_FOUND","title":"Evidence Request Not Found","detail":"No evidence request exists with id '101' for the specified client."}]}}}}}},"500":{"description":"Internal Server Error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"ErrorResponse":{"description":"Represents a generic server failure. The client request was valid, but processing failed due to an internal system error.","value":{"errors":[{"code":"INTERNAL_SERVER_ERROR","title":"Internal server error.","detail":"An unexpected error occurred. Please try again later."}]}}}}}}},"security":[{"apiKey":[]}]}},"/controlmap/v1/clients/{client_id}/evidence-requests/{evidence_request_id}/documents":{"post":{"tags":["Evidences"],"summary":"Upload a document (up to 10 MB) to an evidence request.","description":"Uploads a document up to 10 MB and attaches it to the specified evidence request.\n","operationId":"10_evidenceApi","parameters":[{"name":"client_id","in":"path","description":"Unique identifier for the client (ControlMap tenant or client ID).","required":true,"schema":{"type":"string","format":"uuid","example":"365bcf1e-a26b-4abc-ad9a-8607e2f43910"}},{"name":"evidence_request_id","in":"path","description":"ID of the evidence request.","required":true,"schema":{"type":"integer","example":101}}],"requestBody":{"description":"Multipart form-data payload.\nRequired:\n- file: document binary\n","content":{"multipart/form-data":{"schema":{"type":"object","properties":{"file":{"type":"string","format":"binary","description":"Document file to upload."}},"required":["file"]}}},"required":true},"responses":{"201":{"description":"Ok","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SignedUploadResponse"},"examples":{"SignedUploadResponse":{"summary":"Response containing signed URLs for upload","description":"Indicates that the document(s) have been successfully uploaded and associated with the specified evidence request.","value":{"evidence_request_id":101,"evidence_request_code":"EV-7-4","documents":[{"file_name":"User_Access_Review_Q1_2026.pdf","document_id":501}]}}}}}},"400":{"description":"Bad Request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"ValidationError":{"summary":"Validation errors","description":"Indicates that one or more request parameters are invalid or violates business validation rules. The client must correct the request and retry.","value":{"errors":[{"code":"VALIDATION_ERROR","title":"Invalid Request Parameter","detail":"File size must be greater than 0"}]}}}}}},"401":{"description":"Unauthorized","content":{"application/json":{"examples":{"ErrorResponse":{"description":"Returned when authentication fails due to a missing, invalid, or expired Bearer access token.","value":{"errors":[{"code":"UNAUTHORIZED","title":"Invalid or expired token.","detail":"The provided JWT is invalid or has expired. Please authenticate again and include a valid Bearer token."}]}}}}}},"404":{"description":"Not Found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"ErrorResponse":{"description":"The system was unable to locate the specified client or tenant, or no evidence request exists for the provided ID.","value":{"errors":[{"code":"NOT_FOUND","title":"Evidence Request Not Found","detail":"No evidence request exists with id '101' for the specified client."}]}}}}}},"500":{"description":"Internal Server Error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"ErrorResponse":{"description":"Represents a generic server failure. The client request was valid, but processing failed due to an internal system error.","value":{"errors":[{"code":"INTERNAL_SERVER_ERROR","title":"Internal server error.","detail":"An unexpected error occurred. Please try again later."}]}}}}}}},"security":[{"apiKey":[]}]}},"/controlmap/v1/clients/{client_id}/evidences/{evidence_id}/documents":{"post":{"tags":["Evidences"],"summary":"Create Evidence Request and Upload a document (up to 10 MB)","description":"Creates a new evidence request and uploads a document up to 10 MB, attaching the uploaded\ndocument to the newly created evidence request.\n","operationId":"11_evidenceApi","parameters":[{"name":"client_id","in":"path","description":"Unique identifier for the client (ControlMap tenant or client ID).","required":true,"schema":{"type":"string","format":"uuid","example":"365bcf1e-a26b-4abc-ad9a-8607e2f43910"}},{"name":"evidence_id","in":"path","description":"ID of the evidence.","required":true,"schema":{"type":"integer","example":101}}],"requestBody":{"content":{"multipart/form-data":{"schema":{"type":"object","properties":{"file":{"type":"string","format":"binary"}},"required":["file"]}}},"required":true},"responses":{"201":{"description":"Ok","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SignedUploadResponse"},"examples":{"SignedUploadResponse":{"summary":"Response containing signed URLs for upload","description":"Indicates that the document(s) have been successfully uploaded and associated with the specified evidence request.","value":{"evidence_request_id":101,"documents":[{"file_name":"User_Access_Review_Q1_2026.pdf","document_id":501}]}}}}}},"400":{"description":"Bad Request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"ValidationError":{"summary":"Validation errors","description":"Indicates that the provided file is empty or has an invalid size. The client must correct the request and retry.","value":{"errors":[{"code":"VALIDATION_ERROR","title":"Invalid Request Parameter","detail":"File size must be greater than 0"}]}}}}}},"401":{"description":"Unauthorized","content":{"application/json":{"examples":{"ErrorResponse":{"description":"Returned when authentication fails due to a missing, invalid, or expired Bearer access token.","value":{"errors":[{"code":"UNAUTHORIZED","title":"Invalid or expired token.","detail":"The provided JWT is invalid or has expired. Please authenticate again and include a valid Bearer token."}]}}}}}},"404":{"description":"Not Found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"NotFound":{"description":"The system was unable to locate the specified client or tenant, or no evidence request exists for the provided ID.","value":{"errors":[{"code":"NOT_FOUND","title":"Evidence Request Not Found","detail":"No evidence request exists with id '101' for the specified client."}]}}}}}},"500":{"description":"Internal Server Error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"InternalServerError":{"description":"Represents a generic server failure. The client request was valid, but processing failed due to an internal system error.","value":{"errors":[{"code":"INTERNAL_SERVER_ERROR","title":"Internal server error.","detail":"An unexpected error occurred. Please try again later."}]}}}}}}},"security":[{"apiKey":[]}]}},"/controlmap/v1/clients/{client_id}/evidence-requests/links":{"post":{"tags":["Evidences"],"summary":"Create Link for Evidence Request","description":"Creates a new hyperlink and associates it with an evidence request.\n\nUsed to create:\n- External reference URLs\n- Documentation or shared drive links\n- URL-based supporting evidence\n","operationId":"11_evidenceApi_1","parameters":[{"name":"client_id","in":"path","description":"Unique identifier for the client (ControlMap tenant or client ID).","required":true,"schema":{"type":"string","format":"uuid","example":"365bcf1e-a26b-4abc-ad9a-8607e2f43910"}}],"requestBody":{"description":"Request payload containing the details of the link to be associated with an evidence request.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceLinkCreateRequest"},"example":{"evidence_request_id":102,"name":"SOC 2 Evidence Folder","hyperlink":"https://example.com/resources/12345"}}},"required":true},"responses":{"201":{"description":"OK","content":{"application/json":{"schema":{"type":"string"},"example":{"id":103}}}},"400":{"description":"Bad Request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"ErrorResponse":{"summary":"Multiple validation or business logic errors","description":"Indicates that one or more request parameters are invalid or violates business validation rules. The client must correct the request and retry.","value":{"errors":[{"code":"INVALID_CLIENT","title":"Invalid client identifier.","detail":"The clientId '365bcf1e-a26b-4abc-ad9a-8607e2f43910' is invalid or not registered. Please verify the client ID in the request path."},{"code":"BAD_REQUEST","title":"Failed to read request","detail":"The request body is invalid or malformed. Please ensure the JSON format is correct, and required fields are provided."},{"code":"VALIDATION_ERROR","title":"Invalid Request Parameter","detail":"hyperlink: URL is required"},{"code":"VALIDATION_ERROR","title":"Invalid Request Parameter","detail":"name: Link name is required"}]}}}}}},"401":{"description":"Unauthorized","content":{"application/json":{"examples":{"ErrorResponse":{"description":"Returned when authentication fails due to a missing, invalid, or expired Bearer access token.","value":{"errors":[{"code":"UNAUTHORIZED","title":"Invalid or expired token.","detail":"The provided JWT is invalid or has expired. Please authenticate again and include a valid Bearer token."}]}}}}}},"404":{"description":"Not Found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"ErrorResponse":{"description":"The system was unable to locate the specified client or tenant, or no evidence request exists for the provided ID.","value":{"errors":[{"code":"NOT_FOUND","title":"Not Found","detail":"No evidence request exists with ID '102'."}]}}}}}},"500":{"description":"Internal Server Error","content":{"application/json":{"examples":{"ErrorResponse":{"description":"Represents a generic server failure. The client request was valid, but processing failed due to an internal system error.","value":{"errors":[{"code":"INTERNAL_SERVER_ERROR","title":"Internal server error.","detail":"An unexpected error occurred on the server. Please try again later."}]}}}}}}},"security":[{"apiKey":[]}]}},"/controlmap/v1/clients/{client_id}/evidence-requests/{evidence_request_id}":{"delete":{"tags":["Evidences"],"summary":"Delete Evidence Request","description":"Deletes a specific evidence request associated with an evidence.\n\nThis operation is typically used when:\n- A request was created incorrectly\n- The workflow requires removing outdated or duplicate requests\n- A reviewer needs to invalidate a previous request\n\n**Important:** Deletion may be restricted if evidence contains only one request.\n","operationId":"14_evidenceApi","parameters":[{"name":"client_id","in":"path","description":"Unique identifier for the client (ControlMap tenant or client ID).","required":true,"schema":{"type":"string","format":"uuid","example":"365bcf1e-a26b-4abc-ad9a-8607e2f43910"}},{"name":"evidence_request_id","in":"path","description":"ID of the evidence request.","required":true,"schema":{"type":"integer","example":101}}],"responses":{"204":{"description":"No Content"},"400":{"description":"Bad Request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"badRequest":{"summary":"Invalid path or request values","description":"Indicates that one or more request parameters are invalid or violates business validation rules. The client must correct the request and retry.","value":{"errors":[{"code":"INVALID_CLIENT","title":"Invalid client identifier.","detail":"The clientId '365bcf1e-a26b-4abc-ad9a-8607e2f43910' is invalid or not registered. Please verify the client ID in the request path."}]}}}}}},"401":{"description":"Unauthorized","content":{"application/json":{"examples":{"ErrorResponse":{"description":"Returned when authentication fails due to a missing, invalid, or expired Bearer access token.","value":{"errors":[{"code":"UNAUTHORIZED","title":"Invalid or expired token.","detail":"The provided JWT is invalid or has expired. Please authenticate again and include a valid Bearer token."}]}}}}}},"404":{"description":"Not Found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"ErrorResponse":{"description":"The system was unable to locate the specified client or tenant, or no evidence request for the provided ID.","value":{"errors":[{"code":"NOT_FOUND","title":"Evidence request not found","detail":"No evidence request exists with ID '101'."}]}}}}}},"500":{"description":"Internal Server Error","content":{"application/json":{"examples":{"ErrorResponse":{"description":"Represents a generic server failure. The client request was valid, but processing failed due to an internal system error.","value":{"errors":[{"code":"INTERNAL_SERVER_ERROR","title":"Internal server error.","detail":"An unexpected error occurred on the server. Please try again later."}]}}}}}}},"security":[{"apiKey":[]}]},"patch":{"tags":["Evidences"],"summary":"Partially Update Evidence Request","description":"Updates specific fields of an evidence request. Only provided fields are updated, others remain unchanged.\n\nOnly fields included in the payload will be updated.\nFields omitted will remain unchanged.\n\n**Common Use Cases:**\n- Updating status (**Supported values:**  `Not Started`, `In Progress`, `Review`, `Completed`, `Not Applicable`)\n- Changing Assignee\n- Updating due-date\n- Adding reviewer notes\n","operationId":"12_evidenceApi","parameters":[{"name":"client_id","in":"path","description":"Unique identifier for the client (ControlMap tenant or client ID).","required":true,"schema":{"type":"string","format":"uuid","example":"365bcf1e-a26b-4abc-ad9a-8607e2f43910"}},{"name":"evidence_request_id","in":"path","description":"ID of the evidence request.","required":true,"schema":{"type":"integer","example":102}}],"requestBody":{"description":"JSON payload containing one or more fields to update.\nOnly the fields included in the request will be applied.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceRequestPartialUpdate"},"examples":{"Request Payload":{"summary":"Partial update example","description":"Updates assigned to, status, due date, and reviewer notes.","value":{"assigned_to":"joel@example.com","status":"In Progress","due_date":"2026-01-05","notes":"Reviewed by admin. Waiting for supporting documents."}}}}},"required":true},"responses":{"204":{"description":"No Content"},"400":{"description":"Bad Request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"ErrorResponse":{"summary":"Multiple validation or business logic errors","description":"Indicates that one or more request parameters are invalid or violates business validation rules. The client must correct the request and retry.","value":{"errors":[{"code":"INVALID_CLIENT","title":"Invalid client identifier.","detail":"The clientId '365bcf1e-a26b-4abc-ad9a-8607e2f43910' is invalid or not registered. Please verify the client ID in the request path."},{"code":"BAD_REQUEST","title":"Failed to read request","detail":"The request body is invalid or malformed. Please ensure the JSON format is correct, and required fields are provided."},{"code":"VALIDATION_ERROR","title":"Invalid Request Parameter","detail":"status: must match Not Started|In Progress|Review|Completed|Not Applicable"},{"code":"VALIDATION_ERROR","title":"Invalid assignee email","detail":"No user exists with email 'joel@example.com'."}]}}}}}},"401":{"description":"Unauthorized","content":{"application/json":{"examples":{"ErrorResponse":{"description":"Returned when authentication fails due to a missing, invalid, or expired Bearer access token.","value":{"errors":[{"code":"UNAUTHORIZED","title":"Invalid or expired token.","detail":"The provided JWT is invalid or has expired. Please authenticate again and include a valid Bearer token."}]}}}}}},"404":{"description":"Not Found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"ErrorResponse":{"description":"The system was unable to locate the specified client or tenant, or no evidence request exists for the provided risk ID.","value":{"errors":[{"code":"NOT_FOUND","title":"Evidence request not found","detail":"No evidence request exists with ID '102'."}]}}}}}},"500":{"description":"Internal Server Error","content":{"application/json":{"examples":{"ErrorResponse":{"description":"Represents a generic server failure. The client request was valid, but processing failed due to an internal system error.","value":{"errors":[{"code":"INTERNAL_SERVER_ERROR","title":"Internal server error.","detail":"An unexpected error occurred on the server. Please try again later."}]}}}}}}},"security":[{"apiKey":[]}]}},"/controlmap/v1/clients/{client_id}/evidence-mappings/refresh":{"post":{"tags":["Evidences"],"summary":"Refresh Client Evidence Mappings","description":"Triggers a refresh of all evidence mappings for the specified client.\n\nThis operation is typically used to:\n- Re-sync evidence mappings after changes in configuration\n- Pull updated mapping definitions\n- Recompute mapping relationships for compliance workflows\n","operationId":"13_evidenceApi","parameters":[{"name":"client_id","in":"path","description":"Unique identifier for the client (ControlMap tenant or client ID).","required":true,"schema":{"type":"string","format":"uuid","example":"365bcf1e-a26b-4abc-ad9a-8607e2f43910"}}],"responses":{"200":{"description":"Ok","content":{"application/json":{"schema":{"type":"string","description":"Simple response map containing operation code and message"},"examples":{"EvidenceMappingsRefreshResponse":{"description":"EvidenceMappingsRefreshResponse","value":{"status":"SUCCESS","code":"EVIDENCE_MAPPINGS_REFRESHED","clientId":"365bcf1e-a26b-4abc-ad9a-8607e2f43910","message":"Evidence mappings refreshed successfully."}}}}}},"400":{"description":"Bad Request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"badRequest":{"summary":"Invalid path or request values","description":"Indicates that one or more request parameters are invalid or violates business validation rules. The client must correct the request and retry.","value":{"errors":[{"code":"INVALID_CLIENT","title":"Invalid client identifier.","detail":"The clientId '365bcf1e-a26b-4abc-ad9a-8607e2f43910' is invalid or not registered. Please verify the client ID in the request path."}]}}}}}},"401":{"description":"Unauthorized","content":{"application/json":{"examples":{"ErrorResponse":{"description":"Returned when authentication fails due to a missing, invalid, or expired Bearer access token.","value":{"errors":[{"code":"UNAUTHORIZED","title":"Invalid or expired token.","detail":"The provided JWT is invalid or has expired. Please authenticate again and include a valid Bearer token."}]}}}}}},"500":{"description":"Internal Server Error","content":{"application/json":{"examples":{"ErrorResponse":{"description":"Represents a generic server failure. The client request was valid, but processing failed due to an internal system error.","value":{"errors":[{"code":"INTERNAL_SERVER_ERROR","title":"Internal server error.","detail":"An unexpected error occurred on the server. Please try again later."}]}}}}}}},"security":[{"apiKey":[]}]}},"/controlmap/v1/clients/{client_id}/evidence-requests/{evidence_request_id}/archive":{"post":{"tags":["Evidences"],"summary":"Archive Evidence Request","description":"Archives an existing evidence request and records audit metadata.\n\nThis endpoint is typically used when:\n- A reviewer or system wants to mark an evidence request as archived\n- Workflows require closing outdated or completed requests\n- Auditing requires capturing who performed the archival action\n\n**Behavior:**\n- If the request is already archived, the operation is a **no-op** but still returns HTTP 200.\n- Audit metadata (actor, timestamp, etc.) is recorded for compliance.\n","operationId":"15_evidenceApi","parameters":[{"name":"client_id","in":"path","description":"Unique identifier for the client (ControlMap tenant or client ID).","required":true,"schema":{"type":"string","format":"uuid","example":"365bcf1e-a26b-4abc-ad9a-8607e2f43910"}},{"name":"evidence_request_id","in":"path","description":"ID of the evidence request.","required":true,"schema":{"type":"integer","example":102}}],"responses":{"200":{"description":"Ok","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CmapResponse"},"examples":{"ArchiveSuccess":{"summary":"Evidence request archived","description":"ArchiveSuccess","value":{"id":102,"code":1,"status":true,"message":"Evidence request archived successfully."}}}}}},"400":{"description":"Bad Request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"badRequest":{"summary":"Invalid path or request values","description":"Indicates that one or more request parameters are invalid or violates business validation rules. The client must correct the request and retry.","value":{"errors":[{"code":"INVALID_CLIENT","title":"Invalid client identifier.","detail":"The clientId '365bcf1e-a26b-4abc-ad9a-8607e2f43910' is invalid or not registered. Please verify the client ID in the request path."}]}}}}}},"401":{"description":"Unauthorized","content":{"application/json":{"examples":{"ErrorResponse":{"description":"Returned when authentication fails due to a missing, invalid, or expired Bearer access token.","value":{"errors":[{"code":"UNAUTHORIZED","title":"Invalid or expired token.","detail":"The provided JWT is invalid or has expired. Please authenticate again and include a valid Bearer token."}]}}}}}},"404":{"description":"Not Found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"ErrorResponse":{"description":"The system was unable to locate the specified client or tenant, or no evidence request exists for the provided.","value":{"errors":[{"code":"NOT_FOUND","title":"The requested resource could not be found.","detail":"The requested resource could not be found. Please check the API documentation to ensure the correct URL and version have been used."}]}}}}}},"500":{"description":"Internal Server Error","content":{"application/json":{"examples":{"ErrorResponse":{"description":"Represents a generic server failure. The client request was valid, but processing failed due to an internal system error.","value":{"errors":[{"code":"INTERNAL_SERVER_ERROR","title":"Internal server error.","detail":"An unexpected error occurred on the server. Please try again later."}]}}}}}}},"security":[{"apiKey":[]}]}},"/controlmap/v1/clients/{client_id}/documents/{document_id}":{"get":{"tags":["Documents"],"summary":"Get Document Signed URL","description":"Retrieves a time-limited signed URL for downloading the specified document.\n\nThis is typically used to:\n- Provide secure client-side document downloads\n- Grant temporary access to evidence-related documents\n- Retrieve signed URLs stored in cloud storage\n","operationId":"16_evidenceApi","parameters":[{"name":"client_id","in":"path","description":"Unique identifier for the client (ControlMap tenant or client ID).","required":true,"schema":{"type":"string","format":"uuid","example":"365bcf1e-a26b-4abc-ad9a-8607e2f43910"}},{"name":"document_id","in":"path","description":"Document identifier.","required":true,"schema":{"type":"integer","example":1024}}],"responses":{"200":{"description":"Ok","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DocumentResponse"},"example":{"document_id":1024,"file_name":"firewall-review.pdf","signed_url":"https://signed-url-storage.com/temp/abc123?expiry=2027-01-30T15:28:17.354Z","expires_at":"2027-01-30T15:28:17.354Z"}}}},"400":{"description":"Bad Request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"InvalidClient":{"summary":"Invalid client identifier","description":"Returned when the provided clientId is not valid or not registered.","value":{"errors":[{"code":"INVALID_CLIENT","title":"Invalid client identifier.","detail":"The clientId '365bcf1e-a26b-4abc-ad9a-8607e2f43910' is invalid or not registered. Please verify the client ID in the request path."}]}},"InvalidRequest":{"summary":"Invalid request parameters","description":"Returned when request parameters are missing or invalid.","value":{"errors":[{"code":"INVALID_REQUEST","title":"Bad Request","detail":"One or more request parameters are missing or invalid. Please correct the request and try again."}]}}}}}},"401":{"description":"Unauthorized","content":{"application/json":{"examples":{"ErrorResponse":{"description":"Returned when authentication fails due to a missing, invalid, or expired Bearer access token.","value":{"errors":[{"code":"UNAUTHORIZED","title":"Invalid or expired token.","detail":"The provided JWT is invalid or has expired. Please authenticate again and include a valid Bearer token."}]}}}}}},"404":{"description":"Not Found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"ErrorResponse":{"description":"The system was unable to locate the specified client or tenant.","value":{"errors":[{"code":"NOT_FOUND","title":"Not Found","detail":"The requested document was not found. Please verify the document ID and try again."}]}}}}}},"500":{"description":"Internal Server Error","content":{"application/json":{"examples":{"ErrorResponse":{"description":"Represents a generic server failure. The client request was valid, but processing failed due to an internal system error.","value":{"errors":[{"code":"INTERNAL_SERVER_ERROR","title":"Internal server error.","detail":"An unexpected error occurred on the server. Please try again later."}]}}}}}}},"security":[{"apiKey":[]}]},"delete":{"tags":["Documents"],"summary":"Delete Document","description":"Deletes the specified document for the given client.\n\nUse this endpoint when:\n- An incorrect or duplicate document was uploaded\n- A document must be removed from an evidence request\n- Evidence documentation is no longer required\n","operationId":"17_evidenceApi","parameters":[{"name":"client_id","in":"path","description":"Unique identifier for the client (ControlMap tenant or client ID).","required":true,"schema":{"type":"string","format":"uuid","example":"365bcf1e-a26b-4abc-ad9a-8607e2f43910"}},{"name":"document_id","in":"path","description":"ID of the document.","required":true,"schema":{"type":"integer","example":101}}],"responses":{"204":{"description":"No Content"},"400":{"description":"Bad Request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"badRequest":{"summary":"Invalid document or client identifier","description":"Indicates that one or more request parameters are invalid or violates business validation rules. The client must correct the request and retry.","value":{"errors":[{"code":"INVALID_REQUEST","title":"Bad Request","detail":"One or more path parameters are missing or invalid."}]}}}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"ErrorResponse":{"description":"Returned when authentication fails due to a missing, invalid, or expired Bearer access token.","value":{"errors":[{"code":"UNAUTHORIZED","title":"Invalid or expired token.","detail":"Please authenticate again and include a valid Bearer token."}]}}}}}},"404":{"description":"Not Found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"ErrorResponse":{"description":"The system was unable to locate the specified client or tenant, or no evidence document exists for the provided document ID.","value":{"errors":[{"code":"NOT_FOUND","title":"Document Not Found","detail":"No document exists with id '101' for the specified client."}]}}}}}},"500":{"description":"Internal Server Error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"ErrorResponse":{"description":"Represents a generic server failure. The client request was valid, but processing failed due to an internal system error.","value":{"errors":[{"code":"INTERNAL_SERVER_ERROR","title":"Internal server error.","detail":"An unexpected error occurred on the server. Please try again later."}]}}}}}}},"security":[{"apiKey":[]}]}},"/controlmap/v1/clients/{client_id}/action-items/search":{"post":{"tags":["Action Items"],"summary":"Search Client Action Items","description":"Retrieves a paginated list of action items for a specific client.\n\nSupports filtering with PII, sorting, and cursor-based pagination.\n","operationId":"a_actionitem","parameters":[{"name":"client_id","in":"path","description":"Unique identifier of the client whose action items are being retrieved.","required":true,"schema":{"type":"string"},"example":"365bcf1e-a26b-4abc-ad9a-8607e2f43910"}],"requestBody":{"description":"Request payload containing filters, pagination and sorting options.\n\n**Filtering**\n\nFilters must be passed inside the `filter` object.\n\nSupported fields:\n\n`status`, `code`, `title`, `responsible_person.email`\n\n**Examples**\n\n```\n\"filter\": {\n  \"status\": \"eq:In Progress\",\n  \"code\": \"AI-1\",\n  \"responsible_person.email\": \"john.doe@example.com\"\n}\n```\n\n**Supported status values**\n\n`Not Started`, `In Progress`, `Review`, `Completed`, `Not Applicable`\n\n**Pagination**\n\n- `page_size` default = 50\n- `page_size` max = 200\n\n**Cursor Pagination**\n\n- `cursor` must be Base64 encoded.\n\n**Sorting**\n\nAllowed fields:\n`id`, `code`, `title`, `status`\n\nSorting rules:\n- Ascending → `title` or `+title`\n- Descending → `-title`\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ActionItemQueryRequest"},"examples":{"Example Request":{"description":"Illustrates usage of filters, pagination, cursor-based navigation, and sorting in a single request.Illustrates usage of filters, pagination, cursor-based navigation, and sorting in a single request.","value":{"filter":{"status":"eq:In Progress","code":"AI-1","responsible_person.email":"john.doe@example.com"},"page_size":50,"cursor":"YWJjMTIz","sort":"+title"}}}}},"required":true},"responses":{"200":{"description":"Successfully retrieved client action items","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CursorPaginationResponse"},"examples":{"SuccessResponse":{"summary":"Successful paginated response","description":"Represents a successful response containing a list of Action Item","value":{"client":{"id":"365bcf1e-a26b-4abc-ad9a-8607e2f43910","name":"Joel Tech","tenant_id":"joel1"},"action_summary":{"completed":82,"review":0,"in_progress":0,"not_started":2,"not_applicable":0,"total":84,"completion_percentage":97.6},"action_items":{"data":[{"id":75,"code":"AI-9","weakness_name":"Not Performed: Does the organization continuously monitor inbound and outbound communications traffic for unusual or unauthorized activities or conditions?","weakness_description":"The identified issue has been reviewed and the current status indicates it is ready to proceed.","status":"Not Started","created_by":{"id":1,"name":"Joel Tech","email":"john.tech@example.com"},"responsible_person":{"id":3,"name":"Jhon King","email":"john.doe@example.com"},"updated_at":"2026-03-13T19:26:19","created_at":"2026-03-13T19:26:19","type":"action-item","milestones":"Milestones have been defined to monitor the progress of this action item and ensure that key tasks are completed within the planned timeline","responsible_department":"Operations Management","corrective_action":"Implement the necessary fixes to address the identified issue and ensure the system functions as expected.","priority":"Medium","planned_start_date":"2026-03-01T10:13:03","actual_start_date":"2026-03-04T10:13:03","planned_completion_date":"2026-03-26T10:13:03","actual_completion_date":"2026-03-27T10:13:03","changes_to_milestones":"Milestones have been updated to reflect the latest progress and project requirements.","source_of_weakness":"SYSTEM","requirements":null,"currency":"USD","roadmap":"3 months","cost":56,"effort_in_hours":223},{"id":77,"code":"AI-10","weakness_name":"Not Performed: Does the organization configure systems to produce audit records that contain sufficient information to, at a minimum:  -  Establish what type of event occurred;  -  When (date and time) the event occurred;  -  Where the event occurred;  -  The source of the event;  -  The outcome (success or failure) of the event; and   -  The identity of any user/subject associated with the event?","weakness_description":"The identified issue has been reviewed and the current status indicates it is ready to proceed.","status":"In Progress","created_by":{"id":1,"name":"Joel Tech","email":"joel+cool@controlmap.io"},"responsible_person":{"id":2,"name":"Jhon King","email":"jhon+king@controlmap.io"},"updated_at":"2026-03-13T19:26:21","created_at":"2026-03-13T19:26:21","type":"action-item","milestones":"Milestones have been defined to monitor the progress of this action item and ensure that key tasks are completed within the planned timeline","responsible_department":"Finance","resource_estimate":22,"corrective_action":"Implement the necessary fixes to address the identified issue and ensure the system functions as expected.","priority":"Medium","planned_start_date":"2026-03-03T10:13:03","actual_start_date":"2026-03-12T10:13:03","planned_completion_date":"2026-03-10T10:13:03","actual_completion_date":"2026-03-18T10:13:03","changes_to_milestones":"Milestones have been updated to reflect the latest progress and project requirements.","source_of_weakness":"SYSTEM","requirements":["CYBERSECURITY MATURITY MODEL CERTIFICATION (CMMC 2.0):AC.L1-3.1.2","CYBERSECURITY MATURITY MODEL CERTIFICATION (CMMC 2.0):AC.L1-3.1.22","CYBERSECURITY MATURITY MODEL CERTIFICATION (CMMC 2.0):AC.L1-3.1.20"],"currency":"USD","roadmap":"3 months","cost":22,"effort_in_hours":222.2}],"total_count":1,"next_cursor":"eyJpZCI6MTcxfQ=="}}}}}}},"400":{"description":"Invalid request parameters","content":{"application/json":{"examples":{"ValidationError_PageSize":{"summary":"Page size exceeds maximum allowed limit","description":"Returned when the request contains invalid pagination","value":{"errors":[{"code":"BAD_REQUEST","title":"Validation error.","detail":"page size must be less than or equal to 200"}]}},"InvalidSortField":{"summary":"Invalid sort field","description":"Returned when the request contains an invalid or unsupported sort parameter. The client must provide a valid sort field.","value":{"errors":[{"code":"BAD_REQUEST","title":"Validation error.","detail":"Invalid sort field. Valid fields for Asc are: id, code, title, status. For Asc add '+' before the field name. For Desc add '-' before the field name."}]}},"InvalidFilterField":{"summary":"Invalid filter field","description":"Returned when the request includes an unsupported or invalid filter field. The client must use a valid, filterable field.","value":{"errors":[{"code":"BAD_REQUEST","title":"Invalid Filter","detail":"Filtering is not supported for the field 'title-new'. Please use a valid filterable field."}]}},"InvalidClientId":{"summary":"Invalid client identifier","description":"Indicates that the specified clientId is invalid or not recognized.","value":{"errors":[{"code":"INVALID_CLIENT","title":"Invalid client identifier.","detail":"The clientId 'leno12' is invalid or not registered. Please verify the client ID in the request path."}]}}}}}},"401":{"description":"Unauthorized – Authentication required","content":{"application/json":{"examples":{"Unauthorized":{"description":"Returned when authentication fails due to a missing, invalid, or expired Bearer access token.","value":{"errors":[{"code":"UNAUTHORIZED","title":"Invalid or expired token.","detail":"The provided JWT is invalid or has expired. Please authenticate again and include a valid Bearer token."}]}}}}}},"500":{"description":"Internal server error","content":{"application/json":{"examples":{"InternalServerError":{"description":"Represents a generic server failure. The client request was valid, but processing failed due to an internal system error.","value":{"errors":[{"code":"INTERNAL_SERVER_ERROR","title":"Internal server error.","detail":"An unexpected error occurred on the server. Please try again later."}]}}}}}}},"security":[{"apiKey":[]}]}},"/controlmap/v1/clients/{client_id}/assessments/common/summary":{"get":{"tags":["Assessments"],"summary":"Client Assessment Summary","description":"Returns comprehensive assessment summary for a client.\n\nBy default, the response includes:\n- `assessment_question_groups`\n- `grades`\n- `assessment_stats`\n\nOptional query parameters:\n- `include_framework_assessment_stats=true`: Includes framework-level statistics such as `frameworks_count` and `framework-specific progress` data along with the default response.\n","operationId":"AssessmentProgress","parameters":[{"name":"client_id","in":"path","description":"Client UUID (path segment for API consistency with other client-scoped assessment routes).","required":true,"schema":{"type":"string","format":"uuid"},"example":"365bcf1e-a26b-4abc-ad9a-8607e2f43910"},{"name":"include_framework_assessment_stats","in":"query","description":"When `true`, includes framework-level assessment stats (`frameworks_count` and `frameworks`).\n","required":false,"schema":{"type":"boolean","default":false}}],"responses":{"200":{"description":"Assessment Summary for a client","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AssessmentSummaryDTO"},"examples":{"Assessment Summary Default":{"description":"Default response (include_framework_assessment_stats=false)","value":{"answering_progress":{"total_questions":263,"no":11,"answered_questions":81,"na":5,"yes":58,"partially":7,"answered_questions_percentage":30},"assessment_score_percentage":24,"question_group_progress":[{"no":0,"na":0,"answered":8,"yes":6,"name":"Security & Privacy Governance","count":10,"not_answered":2,"partially":2}]}},"Assessment Summary with Frameworks":{"description":"Response with framework stats (include_framework_assessment_stats=true)","value":{"answering_progress":{"total_questions":263,"no":11,"answered_questions":81,"na":5,"yes":58,"partially":7,"answered_questions_percentage":30},"assessment_score_percentage":24,"question_group_progress":[{"no":0,"na":0,"answered":8,"yes":6,"name":"Security & Privacy Governance","count":10,"not_answered":2,"partially":2}],"frameworks_count":3,"frameworks":[{"framework_id":3,"framework_name":"ISO-27001","answering_progress":{"total_questions":188,"no":9,"answered_questions":57,"na":2,"yes":43,"partially":3,"answered_questions_percentage":30},"assessment_score_percentage":24}]}}}}}},"400":{"description":"Bad Request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"ErrorResponse":{"summary":"Invalid path or request values","description":"Indicates that one or more request parameters are invalid or violates business validation rules. The client must correct the request and retry.","value":{"errors":[{"code":"INVALID_CLIENT","title":"Invalid client identifier.","detail":"The clientId '365bcf1e-a26b-4abc-ad9a-8607e2f43910' is invalid or not registered. Please verify the client ID in the request path."}]}}}}}},"401":{"description":"Unauthorized - Authentication required","content":{"application/json":{"examples":{"ErrorResponse":{"description":"Returned when authentication fails due to a missing, invalid, or expired Bearer access token.","value":{"errors":[{"code":"UNAUTHORIZED","title":"Invalid or expired token.","detail":"The provided JWT is invalid or has expired. Please authenticate again and include a valid Bearer token."}]}}}}}},"500":{"description":"Internal Server Error","content":{"application/json":{"examples":{"ErrorResponse":{"description":"Represents a generic server failure. The client request was valid, but processing failed due to an internal system error.","value":{"errors":[{"code":"INTERNAL_SERVER_ERROR","title":"Internal server error.","detail":"An unexpected error occurred on the server. Please try again later."}]}}}}}}},"security":[{"apiKey":[]}]}},"/controlmap/v1/clients/{client_id}/assessments/common/questions/{question_code}/answer":{"put":{"tags":["Assessments"],"summary":"Save Assessment Question Answer","description":"Submits or updates the selected answer for the assessment question identified by `question_code`.\n\nThe `answer` value must match one of the valid response options for that question.\n\n**Supported answer values:**\n   Yes, No, Partially, NA\n","operationId":"assessmentQuestionPutAnswerForClient","parameters":[{"name":"client_id","in":"path","description":"Client UUID.","required":true,"schema":{"type":"string","format":"uuid"},"example":"365bcf1e-a26b-4abc-ad9a-8607e2f43910"},{"name":"question_code","in":"path","description":"External question code or identifier used to resolve the question (path segment name is `question_code` for URL compatibility).","required":true,"schema":{"type":"string"},"example":"Q-GOV-01"}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AssessmentAnswerPutRequest"},"examples":{"PutAssessmentAnswer":{"description":"Provide the answer label to store for the question.","value":{"answer":"Yes"}}}}},"required":true},"responses":{"200":{"description":"Answer saved successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AssessmentAnswerResponse"},"examples":{"AnswerSaved":{"description":"Response returned after successfully saving or updating an assessment question answer","value":{"question_code":"Q-GOV-01","answer":"Yes","answered_by":{"id":1,"name":"Aditya Kumar"},"reset_answer":false,"answered_at":"2025-09-15"}}}}}},"400":{"description":"Bad Request — validation failed, missing answer, or answer not valid for the question","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"ValidationError":{"description":"Validation error response for malformed or incorrect request payload.","value":{"errors":[{"code":"BAD_REQUEST","title":"Validation failed","detail":"The request body does not satisfy validation constraints."}]}},"AnswerOptionNotFound":{"description":"Answer label does not match any option for the question.","value":{"errors":[{"code":"NOT_FOUND","title":"Not Found","detail":"Answer not found for this question"}]}}}}}},"401":{"description":"Unauthorized","content":{"application/json":{"examples":{"ErrorResponse":{"description":"Returned when authentication fails due to a missing, invalid, or expired Bearer access token.","value":{"errors":[{"code":"UNAUTHORIZED","title":"Invalid or expired token.","detail":"The provided JWT is invalid or has expired."}]}}}}}},"404":{"description":"Assessment Question Not Found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"ErrorResponse":{"description":"Returned when no response is found for the specified assessment question.","value":{"errors":[{"code":"NOT_FOUND","title":"Not Found","detail":"Assessment question not found."}]}}}}}},"500":{"description":"Internal Server Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"ErrorResponse":{"description":"Represents a generic server failure. The client request was valid, but processing failed due to an internal system error.","value":{"errors":[{"code":"INTERNAL_SERVER_ERROR","title":"The server was unable to process the request.","detail":"The server was unable to process the request. Please try again later."}]}}}}}}},"security":[{"apiKey":[]}]},"delete":{"tags":["Assessments"],"summary":"Clear Assessment Question Answer","description":"Clears the existing answer for the specified assessment question.\n\nThis operation removes the stored answer and resets the question to an unanswered state.\n\n","operationId":"assessmentQuestionDeleteAnswerForClient","parameters":[{"name":"client_id","in":"path","description":"Client UUID.","required":true,"schema":{"type":"string","format":"uuid"},"example":"365bcf1e-a26b-4abc-ad9a-8607e2f43910"},{"name":"question_code","in":"path","description":"External question code or identifier used to resolve the question (path segment name is `question_code` for URL compatibility).","required":true,"schema":{"type":"string"},"example":"Q-GOV-01"}],"responses":{"204":{"description":"No Content"},"401":{"description":"Unauthorized","content":{"application/json":{"examples":{"ErrorResponse":{"description":"Returned when authentication fails due to a missing, invalid, or expired Bearer access token.","value":{"errors":[{"code":"UNAUTHORIZED","title":"Invalid or expired token.","detail":"The provided JWT is invalid or has expired."}]}}}}}},"404":{"description":"Assessment Question Not Found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"ErrorResponse":{"description":"Returned when no assessment question is found.","value":{"errors":[{"code":"NOT_FOUND","title":"Not Found","detail":"Assessment question not found."}]}}}}}},"500":{"description":"Internal Server Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"ErrorResponse":{"description":"Represents a generic server failure. The client request was valid, but processing failed due to an internal system error.","value":{"errors":[{"code":"INTERNAL_SERVER_ERROR","title":"The server was unable to process the request.","detail":"The server was unable to process the request. Please try again later."}]}}}}}}},"security":[{"apiKey":[]}]}},"/controlmap/v1/clients/{client_id}/assessments/common/questions/{question_code}":{"get":{"tags":["Assessments"],"summary":"Get Assessment Question","description":"Returns full assessment question details for the question identified by **question code**.\n\n","operationId":"assessmentQuestionGetByCodeForClient","parameters":[{"name":"client_id","in":"path","description":"Client UUID.","required":true,"schema":{"type":"string","format":"uuid"},"example":"365bcf1e-a26b-4abc-ad9a-8607e2f43910"},{"name":"question_code","in":"path","description":"Question code","required":true,"schema":{"type":"string"},"example":"Q-GOV-01"}],"responses":{"200":{"description":"SuccessResponse","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AssessmentQuestionResponse"},"examples":{"SuccessResponse":{"description":"Full Assessment Question Details","value":{"id":3,"code":"Q-GOV-01","owner":{"id":1,"full_name":"John Doe"},"question":"Does the organization staff a function to centrally-govern cybersecurity and privacy controls?","status":"Not Started","auditor_status":"With Customer","answer_options":[{"id":1,"answer":"Yes","order":1},{"id":2,"answer":"No","order":2},{"id":4,"answer":"Partially","order":3},{"id":3,"answer":"NA","order":4}],"action_items":[{"id":217,"title":"test summary","code":"AI-1","description":"test description","due_at":"2026-03-31"}],"objectives":[{"id":279,"code":"A5.1.1","name":"Policies for information security","program_name":"ISO-27001"}],"delegated_to":{},"assessment_status":{},"assessment_auditor_status":{},"responses":[{"id":3,"response":"Updated after follow-up call.","created_at":"2026-03-27","updated_at":"2026-03-27","created_by":{"id":1,"full_name":"John Doe"}}],"answer":"yes","group_name":"Security & Privacy Governance","illustrative_example":"<strong>Significance of this question</strong><br><br>1. Consistent Implementation of Policies: With a specific function or team in place, cybersecurity and privacy controls can be governed in a consistent manner throughout the organization. This consistency is important in ensuring all data is protected equally and there are no gaps in security.","policies":[{"id":1,"policy_code":"POL-1","name":"Acceptable Use Policy"}],"procedures":[{"id":23,"name":"Procedure for control of documented information","procedure_code":"PRO-1"}],"evidences":[{"id":102,"title":"Procedures for handling job role changes, reassignments and promotions","evidence_code":"EV-4"}],"past_answer":"Partially"}}}}}},"404":{"description":"Question Code Not Found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"ErrorResponse":{"description":"Returned when no assessment question is found.","value":{"errors":[{"code":"NOT_FOUND","title":"Not Found","detail":"Assessment question not found."}]}}}}}},"500":{"description":"Internal Server Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"ErrorResponse":{"description":"Represents a generic server failure. The client request was valid, but processing failed due to an internal system error.","value":{"errors":[{"code":"INTERNAL_SERVER_ERROR","title":"The server was unable to process the request.","detail":"The server was unable to process the request. Please try again later."}]}}}}}}},"security":[{"apiKey":[]}]}},"/controlmap/v1/clients/{client_id}/assessments/common/questions/{question_code}/mappings":{"post":{"tags":["Assessments"],"summary":"Map Assessment Question to Evidences, Action Items, Policies, or Procedures","description":"Maps an assessment question to evidences, action items, policies, or procedures for a client.\n\nIn the request body, include only the entity codes/IDs that need to be mapped.\nEmpty or omitted arrays are ignored.\n\nSupported request fields:\n- evidence_codes\n- action_item_codes\n- policy_codes\n- procedure_codes\n","operationId":"assessmentQuestionMapEntitiesForClient","parameters":[{"name":"client_id","in":"path","description":"Client UUID.","required":true,"schema":{"type":"string","format":"uuid"},"example":"365bcf1e-a26b-4abc-ad9a-8607e2f43910"},{"name":"question_code","in":"path","description":"Question code.","required":true,"schema":{"type":"string"},"example":"Q-GOV-01"}],"requestBody":{"description":"Provide the entity codes or IDs to be mapped to the assessment question. Include only the fields that need to be mapped; empty or omitted fields will be ignored.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AssessmentQuestionMapRequest"},"examples":{"mapWithMultipleEntities":{"description":"Specify only the entity codes/IDs to map to the assessment question; other fields can be omitted.","value":{"evidence_codes":["FG-001","EV-100"],"action_item_codes":["AI-1001"],"policy_codes":["POL-1"],"procedure_codes":["PRO-1"]}}}}},"required":true},"responses":{"204":{"description":"Mappings applied (no response body)"},"400":{"description":"Bad Request — validation failed or invalid payload","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"ErrorResponse":{"description":"Validation error response for malformed or incorrect request payload.","value":{"errors":[{"code":"BAD_REQUEST","title":"Validation failed","detail":"The request body does not satisfy validation constraints."}]}}}}}},"404":{"description":"Question Code Not Found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"ErrorResponse":{"description":"Returned when no assessment question is found.","value":{"errors":[{"code":"NOT_FOUND","title":"Not Found","detail":"Assessment question not found."}]}}}}}},"500":{"description":"Internal Server Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"ErrorResponse":{"description":"Represents a generic server failure. The client request was valid, but processing failed due to an internal system error.","value":{"errors":[{"code":"INTERNAL_SERVER_ERROR","title":"The server was unable to process the request.","detail":"The server was unable to process the request. Please try again later."}]}}}}}}},"security":[{"apiKey":[]}]},"delete":{"tags":["Assessments"],"summary":"Unmap Assessment Question from Evidences, Action Items, Policies, or Procedures","description":"Removes links between an assessment question and the given evidences, action items, policies, or procedures for a client.\n\n","operationId":"assessmentQuestionUnmapEntitiesForClient","parameters":[{"name":"client_id","in":"path","description":"Client UUID.","required":true,"schema":{"type":"string","format":"uuid"},"example":"365bcf1e-a26b-4abc-ad9a-8607e2f43910"},{"name":"question_code","in":"path","description":"External question identifier (`externalid`).","required":true,"schema":{"type":"string"},"example":"Q-GOV-01"}],"requestBody":{"description":"Entity codes to remove from the question","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AssessmentQuestionMapRequest"},"examples":{"UnmapEvidences":{"description":"Specify only the evidence, action item, policies or procedures IDs that need to be unmapped from the assessment question. Fields can be left empty if no changes are required.","value":{"evidence_codes":["FG-001","EV-100"],"action_item_codes":["AI-1001"],"policy_codes":["POL-1"],"procedure_codes":["PRO-1"]}}}}},"required":true},"responses":{"204":{"description":"Unmap applied; empty lists result in no changes (no body)"},"400":{"description":"Bad Request — validation failed or invalid payload","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"ErrorResponse":{"description":"Indicates that one or more request parameters are invalid or violates business validation rules. The client must correct the request and retry.","value":{"errors":[{"code":"BAD_REQUEST","title":"Validation failed","detail":"The request body does not satisfy validation constraints."}]}}}}}},"404":{"description":"Assessment Question Not Found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"ErrorResponse":{"description":"The system was unable to locate the specified client or tenant, or no question exists for the provided question code.","value":{"errors":[{"code":"NOT_FOUND","title":"Not Found","detail":"Assessment question not found."}]}}}}}},"500":{"description":"Internal Server Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"ErrorResponse":{"description":"Represents a generic server failure. The client request was valid, but processing failed due to an internal system error.","value":{"errors":[{"code":"INTERNAL_SERVER_ERROR","title":"The server was unable to process the request.","detail":"The server was unable to process the request. Please try again later."}]}}}}}}},"security":[{"apiKey":[]}]}},"/controlmap/v1/clients/{client_id}/assessments/common/questions/{question_code}/responses":{"post":{"tags":["Assessments"],"summary":"Create Assessment Question Response","description":"Creates a response for a client's assessment question\n","operationId":"assessmentQuestionNoteCreate","parameters":[{"name":"client_id","in":"path","description":"Client UUID.","required":true,"schema":{"type":"string","format":"uuid"},"example":"365bcf1e-a26b-4abc-ad9a-8607e2f43910"},{"name":"question_code","in":"path","description":"External question code used to resolve the question","required":true,"schema":{"type":"string"},"example":"Q-GOV-01"}],"requestBody":{"description":"Response text and optional provider label","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AssessmentQuestionResponseCreateRequest"},"examples":{"AddAssessmentQuestionResponse":{"description":"Creates a response for a client's assessment question, including the response text and the provider who added it.","value":{"response":"Evidence reviewed and accepted.","provided_by":"Jane Auditor"}}}}},"required":true},"responses":{"201":{"description":"Assessment Question Response Created Successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AssessmentQuestionNoteResponse"},"examples":{"SuccessResponse":{"description":"Assessment Question Response Created Successfully","value":{"id":5,"question_code":"Q-GOV-01","response":"Evidence reviewed and accepted.","provided_by":"Jane Auditor","created_at":"2026-03-30","updated_at":"2026-03-30","created_by":{"id":1,"full_name":"John Doe"}}}}}}},"400":{"description":"Bad Request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"ErrorResponse":{"description":"Returned when the request fails validation, such as when required fields (e.g., response) are missing or invalid.","value":{"errors":[{"code":"BAD_REQUEST","title":"Validation failed","detail":"response must not be blank"}]}}}}}},"404":{"description":"Assessment Question Not Found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"ErrorResponse":{"description":"Returned when the requested assessment question does not exist for the given identifiers.","value":{"errors":[{"code":"NOT_FOUND","title":"Not Found","detail":"Assessment question not found."}]}}}}}},"500":{"description":"Internal Server Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"ErrorResponse":{"description":"Represents a generic server failure. The client request was valid, but processing failed due to an internal system error.","value":{"errors":[{"code":"INTERNAL_SERVER_ERROR","title":"Internal server error.","detail":"An unexpected error occurred."}]}}}}}}},"security":[{"apiKey":[]}]},"patch":{"tags":["Assessments"],"summary":"Update Assessment Question Response","description":"Partially updates a question response. You can update either or both fields: response and provided_by.\n","operationId":"assessmentQuestionResponseUpdate","parameters":[{"name":"client_id","in":"path","description":"Client UUID.","required":true,"schema":{"type":"string","format":"uuid"},"example":"365bcf1e-a26b-4abc-ad9a-8607e2f43910"},{"name":"question_code","in":"path","description":"External question code used to resolve the question","required":true,"schema":{"type":"string"},"example":"1.2.3"}],"requestBody":{"description":"Response id, updated text, and optional provider label","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AssessmentQuestionResponseUpdateRequest"},"examples":{"UpdateResponseRequest":{"description":"Represents a partial update to a question response, including updated response text and/or provider information.","value":{"id":88,"response":"Updated after follow-up call.","provided_by":"Jane Auditor"}}}}},"required":true},"responses":{"200":{"description":"Response updated","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AssessmentQuestionNoteResponse"},"examples":{"SuccessResponse":{"description":"Represents a successfully updated question response with the latest details.","value":{"id":3,"question_id":3,"response":"Evidence reviewed and accepted.","provided_by":"Jane Auditor","created_at":"2026-03-27","updated_at":"2026-03-27","created_by":{"id":1,"full_name":"Joel King"}}}}}}},"400":{"description":"Validation failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"ErrorResponse":{"description":"Validation error response for malformed or incorrect request payload.","value":{"errors":[{"code":"BAD_REQUEST","title":"Validation failed","detail":"Invalid request body"}]}}}}}},"404":{"description":"Question Response Not Found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"ErrorResponse":{"description":"Returned when no response is found for the specified assessment question.","value":{"errors":[{"code":"NOT_FOUND","title":"Not Found","detail":"Response not found for this question."}]}}}}}},"500":{"description":"Internal Server Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"serverError":{"description":"Represents a generic server failure. The client request was valid, but processing failed due to an internal system error.","value":{"errors":[{"code":"INTERNAL_SERVER_ERROR","title":"Internal server error.","detail":"An unexpected error occurred."}]}}}}}}},"security":[{"apiKey":[]}]}},"/controlmap/v1/clients/{client_id}/assessments/common/questions/{question_code}/responses/{response_id}":{"delete":{"tags":["Assessments"],"summary":"Delete Assessment Question Response","description":"Deletes a assessment question response.\nThe note must belong to the question.\n","operationId":"assessmentQuestionResponseDelete","parameters":[{"name":"client_id","in":"path","description":"Client UUID.","required":true,"schema":{"type":"string","format":"uuid"},"example":"365bcf1e-a26b-4abc-ad9a-8607e2f43910"},{"name":"question_code","in":"path","description":"External question code used to resolve the question","required":true,"schema":{"type":"string"},"example":"1.2.3"},{"name":"response_id","in":"path","description":"Primary key of the response id","required":true,"schema":{"type":"integer","format":"int32"},"example":88}],"responses":{"204":{"description":"No Content"},"404":{"description":"Question Response Not Found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"ErrorResponse":{"description":"Requested Question Response not found","value":{"errors":[{"code":"NOT_FOUND","title":"Not Found","detail":"Response not found for this question."}]}}}}}},"500":{"description":"Internal Server Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"ErrorResponse":{"description":"Represents a generic server failure. The client request was valid, but processing failed due to an internal system error.","value":{"errors":[{"code":"INTERNAL_SERVER_ERROR","title":"Internal server error.","detail":"An unexpected error occurred."}]}}}}}}},"security":[{"apiKey":[]}]}},"/controlmap/v1/clients/{client_id}/assessments/common/questions":{"post":{"tags":["Assessments"],"summary":"Search Client Assessment Questions","description":"Returns a paginated list of assessment questions for the specified client.\n\n        Supports filtering with PII, sorting, and cursor-based pagination..\n","operationId":"assessmentQuestionsSearchByClient","parameters":[{"name":"client_id","in":"path","description":"Unique identifier of the client whose assessment questions are being retrieved.","required":true,"schema":{"type":"string"},"example":"365bcf1e-a26b-4abc-ad9a-8607e2f43910"}],"requestBody":{"description":"Request payload containing filtering, pagination, and sorting options.\n\n**Filtering**\n\nFilters must be provided inside the `filter` object.\n\nSupported fields:\n- `frameworks.name` — Name of the framework.\n- `group_name` — Name of the question group.\n- `answer` — Answer text.\n\nSupported operators (prefix before `:`):\n- `eq` — exact match (default if no operator is provided)\n- `in` — comma-separated list (where applicable)\n- `like` — pattern match (e.g. `%SOC%`)\n\nExample:\n```\n\"filter\": {\n  \"frameworks.name\": \"eq:ISO 27001\",\n  \"group_name\": \"eq:Security\",\n  \"answer\": \"Yes\"\n}\n```\n\nExample with pattern match:\n```\n\"frameworks.name\": \"like:%SOC%\"\n```\n\nExample matching any of several framework names (`in`):\n```\n\"filter\": {\n  \"frameworks.name\": \"in:ISO 27001, SOC 2, PCI DSS\"\n}\n```\n\n**Pagination**\n\n- `page_size` default = 50\n- `page_size` max = 200\n\n**Cursor Pagination**\n\n- `cursor` must be Base64-encoded.\n- Use `next_cursor` from the previous response to retrieve the next page.\n\n**Sorting**\n\nAllowed fields:\n`code`, `group_name`\n\nSorting rules:\n- Ascending → `code` or `+code`\n- Descending → `-code`\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AssessmentQuestionsQueryRequest"},"examples":{"Example Request":{"description":"Example request using filters, pagination, cursor, and sorting.","value":{"filter":{"frameworks.name":"eq:ISO 27001","group_name":"eq:Security","answer":"Yes"},"fields":"code,question,frameworks","page_size":50,"cursor":"YWJjMTIz"}}}}},"required":true},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CursorPaginationResponse"},"examples":{"SuccessResponse":{"summary":"Successful paginated response","description":"Represents a paginated list of assessment questions with their responses, metadata, and associated frameworks.","value":{"data":[{"id":3,"code":"Q-GOV-01","question":"Is access reviewed quarterly?","updated_at":"2025-09-15","created_at":"2025-09-10","answer":"Yes","answered_at":"2025-09-12","guidance":"Refer to access review policy.","frameworks":[{"id":2,"name":"ISO-27001:2022"},{"id":3,"name":"SOC 2"}],"question_area":"Access","responses":[{"id":1,"response":"Refer to access review","created_at":"2026-03-23","updated_at":"2026-03-23","created_by":{"id":1,"full_name":"John Doe","email":"john.doe@example.com"}}],"group_name":"Security","past_answer":null}],"total_count":150,"next_cursor":"eyJpZCI6Mn0="}},"EmptyResult":{"summary":"No matching questions","description":"Valid response when no records match the filters.","value":{"data":[],"total_count":0,"next_cursor":null}}}}}},"400":{"description":"Bad Request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"InvalidFilterField":{"summary":"Invalid filter field","description":"Returned when an unsupported filter field is used.","value":{"errors":[{"code":"BAD_REQUEST","title":"Invalid Filter","detail":"Filtering is not supported for the field 'unknown_field'. Please use a valid filterable field (frameworks.name, group_name, answer)."}]}},"ValidationError_PageSize":{"summary":"Page size exceeds limit","description":"Returned when page_size exceeds the maximum allowed value.","value":{"errors":[{"code":"BAD_REQUEST","title":"Validation error.","detail":"page size must be less than or equal to 200"}]}},"InvalidCursor":{"summary":"Invalid cursor format","description":"Returned when the cursor is not valid Base64.","value":{"errors":[{"code":"BAD_REQUEST","title":"Validation error.","detail":"Cursor must be Base64"}]}}}}}},"401":{"description":"Unauthorized","content":{"application/json":{"examples":{"Unauthorized":{"description":"Returned when authentication fails due to an invalid or expired token.","value":{"errors":[{"code":"UNAUTHORIZED","title":"Invalid or expired token.","detail":"The provided JWT is invalid or has expired. Please authenticate again and include a valid Bearer token."}]}}}}}},"404":{"description":"Client Not Found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"NotFoundError":{"description":"Returned when the specified client does not exist.","value":{"errors":[{"code":"NOT_FOUND","title":"Client Not Found","detail":"The specified client does not exist or is not associated with the tenant."}]}}}}}},"500":{"description":"Internal Server Error","content":{"application/json":{"examples":{"InternalServerError":{"description":"Represents a generic server failure. The client request was valid, but processing failed due to an internal system error.","value":{"errors":[{"code":"INTERNAL_SERVER_ERROR","title":"Internal server error.","detail":"An unexpected error occurred. Please try again later."}]}}}}}}},"security":[{"apiKey":[]}]}},"/controlmap/v1/clients/{client_id}/action-items/{action_item_id}":{"get":{"tags":["Action Items"],"summary":"Get Action Item","description":"Retrieves a specific action item for a given client.\n\nThis endpoint returns detailed information about an action item,\nincluding its status, ownership, and audit metadata.\n","operationId":"b_actionitem","parameters":[{"name":"client_id","in":"path","description":"Unique identifier of the client.\n\nThis identifies the client under which the action item exists.\n","required":true,"schema":{"type":"string","format":"uuid"},"example":"365bcf1e-a26b-4abc-ad9a-8607e2f43910"},{"name":"action_item_id","in":"path","description":"Unique identifier of the action item.\n\nThis identifies the specific action item to retrieve.\n","required":true,"schema":{"type":"integer"},"example":171}],"responses":{"200":{"description":"Action item retrieved successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ActionItemResponse"},"examples":{"Success":{"summary":"Successful response","description":"Successful response containing detailed information of a specific action item.","value":{"id":75,"code":"AI-9","weakness_name":"Not Performed: Does the organization continuously monitor inbound and outbound communications traffic for unusual or unauthorized activities or conditions?","weakness_description":"The weakness has been analyzed and documented, and the necessary details are in place to proceed with remediation activities.","status":"Not Started","created_by":{"id":1,"name":"Joel Tech"},"responsible_person":{"id":3,"name":"John King"},"updated_at":"2026-03-13T19:26:19","created_at":"2026-03-13T19:26:19","type":"action-item","milestones":"Milestones have been defined to monitor the progress of this action item and ensure that key tasks are completed within the planned timeline","responsible_department":"Operations Management","corrective_action":"Implement the necessary fixes to address the identified issue and ensure the system functions as expected.","priority":"Medium","planned_start_date":"2026-03-20","planned_end_date":"2026-04-20","actual_start_date":"2026-03-25","actual_end_date":"2026-04-30","changes_to_milestones":"Milestones have been updated to reflect the latest progress and project requirements.","source_of_weakness":"SYSTEM","requirements":null,"currency":"USD","roadmap":"3 months","cost":56,"effort_in_hours":223,"documents":[{"id":1,"file_name":"demo-file-1.png"},{"id":2,"file_name":"sample-image-2.jpg"}]}}}}}},"400":{"description":"Bad Request","content":{"application/json":{"examples":{"ErrorResponse":{"description":"Indicates that one or more request parameters are invalid or violates business validation rules. The client must correct the request and retry.","value":{"errors":[{"code":"INVALID_CLIENT","title":"Invalid client identifier.","detail":"The clientId 'arch434' is invalid or not registered. Please verify the client ID in the request path."}]}}}}}},"401":{"description":"Unauthorized","content":{"application/json":{"examples":{"ErrorResponse":{"description":"Returned when authentication fails due to a missing, invalid, or expired Bearer access token.","value":{"errors":[{"code":"UNAUTHORIZED","title":"Invalid or expired token.","detail":"The provided JWT is invalid or has expired. Please authenticate again and include a valid Bearer token."}]}}}}}},"404":{"description":"Action item not found","content":{"application/json":{"examples":{"ErrorResponse":{"description":"The system was unable to locate the specified client or tenant, or no action item exists for the provided action item ID.","value":{"errors":[{"code":"NOT_FOUND","title":"Not Found","detail":"Action Item not found: 2"}]}}}}}},"500":{"description":"Internal Server Error","content":{"application/json":{"examples":{"ErrorResponse":{"description":"Represents a generic server failure. The client request was valid, but processing failed due to an internal system error.","value":{"errors":[{"code":"INTERNAL_SERVER_ERROR","title":"Internal server error.","detail":"An unexpected error occurred on the server. Please try again later."}]}}}}}}},"security":[{"apiKey":[]}]},"patch":{"tags":["Action Items"],"summary":"Partially update an action item","description":"Updates specific fields of an action item request. Only the fields provided in the request body will be updated.\nAll other fields will remain unchanged.\n\n**Allowed values for patchable fields:**\n\n - **status**: `Not Started`, `In Progress`, `Review`, `Completed`, `Not Applicable`\n - **roadmap**: `3 months`, `6 months`, `12 months`\n - **priority**: `High`, `Medium`, `Low`, `Critical`\n - **currency**: `USD`, `EUR`, `AUD`, `CAD`, `SEK`, `NZD`, `SGD`, `INR`\n - **efforts_in_hours**: must be zero or a positive number\n - **cost**: must be zero or a positive number\n","operationId":"patchActionItemRequest","parameters":[{"name":"client_id","in":"path","description":"Unique identifier for the client (ControlMap tenant or client ID).","required":true,"schema":{"type":"string"},"example":"365bcf1e-a26b-4abc-ad9a-8607e2f43910"},{"name":"action_item_id","in":"path","description":"Unique identifier of the action item request to be updated","required":true,"schema":{"type":"integer","format":"int32"},"example":1}],"requestBody":{"description":"Fields to update for the action item. Only provided fields will be modified.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ActionItemRequestPartialUpdate"},"examples":{"PatchActionItemRequest":{"summary":"Update action item fields","description":"Partial update request for an action item where only provided fields are modified.","value":{"weakness_name":"Implement security patch","weakness_description":"Update all production servers with the latest security patches to address CVE-2023-1234","status":"Not Started","corrective_action":"Install security updates","responsible_person":"john.doe@scalepad.com","responsible_department":"Sales","efforts_in_hours":8,"roadmap":"3 months","priority":"High","planned_start_date":"2026-03-20","planned_end_date":"2026-04-20","actual_start_date":"2026-03-25","actual_end_date":"2026-04-30","currency":"USD","cost":50,"milestones":"Milestone 1: Planning complete\nMilestone 2: Implementation complete\nMilestone 3: Testing complete","change_in_milestone":"Extended testing phase by 1 week due to additional security requirements"}}}}},"required":true},"responses":{"200":{"description":"Action item updated successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ActionPatchResponse"},"examples":{"ActionItemPatchSuccess":{"summary":"Successful action item update response","description":"Partial update response for an action item where only provided fields are modified.","value":{"id":665,"status":"Not Started","weakness_name":"Implement security patch","weakness_description":"Update all production servers with the latest security patches to address CVE-2023-1234","corrective_action":"Install security updates","responsible_person":"john.doe@scalepad.com","responsible_department":"Sales","efforts":8,"roadmap":"3 months","planned_start_date":"2026-03-20","planned_end_date":"2026-04-20","actual_start_date":"2026-03-25","actual_end_date":"2026-04-30","currency":"USD","priority":"High","cost":50,"milestones":"Milestone 1: Planning complete\nMilestone 2: Implementation complete\nMilestone 3: Testing complete","change_in_milestone":"Extended testing phase by 1 week due to additional security requirements"}}}}}},"400":{"description":"Invalid input or validation error","content":{"application/json":{"examples":{"InvalidStatus":{"summary":"Invalid status value","description":"Indicates that one or more request parameters are invalid or violates business validation rules. The client must correct the request and retry.","value":{"errors":[{"code":"BAD_REQUEST","title":"Bad Request","detail":"Invalid status. Allowed values are: Not Started, In Progress, Review, Completed, Not Applicable"}]}},"SameStatusUpdate":{"summary":"Status update to same value","description":"Occurs when an attempt is made to update the status to the same value that is already set.","value":{"errors":[{"code":"BAD_REQUEST","title":"Bad Request","detail":"Status cannot be updated to the same value"}]}},"InvalidClientId":{"summary":"Invalid client identifier","description":"Occurs when the provided clientId does not exist or is not registered in the system.","value":{"errors":[{"code":"INVALID_CLIENT","title":"Invalid client identifier.","detail":"The clientId 'leno12' is invalid or not registered. Please verify the client ID in the request path."}]}}}}}},"401":{"description":"Unauthorized","content":{"application/json":{"examples":{"ErrorResponse":{"description":"Returned when authentication fails due to a missing, invalid, or expired Bearer access token.","value":{"errors":[{"code":"UNAUTHORIZED","title":"Invalid or expired token.","detail":"The provided JWT is invalid or has expired. Please authenticate again and include a valid Bearer token."}]}}}}}},"404":{"description":"Resource not found","content":{"application/json":{"examples":{"ActionItemNotFound":{"summary":"Action item does not exist","description":"Occurs when the requested action item cannot be found for the given identifier.","value":{"errors":[{"code":"NOT_FOUND","title":"Not Found","detail":"Action Item not found: 1"}]}},"UserNotFound":{"summary":"Assigned user does not exist","description":"Occurs when the provided assignedTo value does not match any existing user in the system.","value":{"errors":[{"code":"NOT_FOUND","title":"Not Found","detail":"Invalid assignedTo value. User not found: john@example.com"}]}}}}}},"500":{"description":"Internal Server Error","content":{"application/json":{"examples":{"ErrorResponse":{"description":"Represents a generic server failure. The client request was valid, but processing failed due to an internal system error.","value":{"errors":[{"code":"INTERNAL_SERVER_ERROR","title":"Internal server error.","detail":"An unexpected error occurred on the server. Please try again later."}]}}}}}}},"security":[{"apiKey":[]}]}},"/controlmap/v1/clients/{client_id}/action-items/{action_item_id}/documents":{"post":{"tags":["Action Items"],"summary":"Upload Document to Action Item (upto 10 MB)","description":"Uploads a document  up to 10 MB and associates it with the specified action item.\nThe file is uploaded as multipart/form-data.\n","operationId":"c_actionitem","parameters":[{"name":"client_id","in":"path","description":"Unique identifier for the client (ControlMap tenant or client ID).","required":true,"schema":{"type":"string","format":"uuid","example":"365bcf1e-a26b-4abc-ad9a-8607e2f43910"}},{"name":"action_item_id","in":"path","description":"ID of the action item.","required":true,"schema":{"type":"integer","example":101}}],"requestBody":{"content":{"multipart/form-data":{"schema":{"type":"object","properties":{"file":{"type":"string","format":"binary"}},"required":["file"]}}}},"responses":{"200":{"description":"Response containing document metadata such as file name and document ID.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DocumentUploadResponse"},"examples":{"DocumentUploadResponse":{"summary":"Response containing document metadata","description":"Represents a successful response containing document metadata for an action item, including file names and their corresponding document IDs for the uploaded files.","value":{"id":"101","code":"AI-9-2","documents":[{"file_name":"User_Access_Review_Q1_2026.pdf","document_id":501}]}}}}}},"400":{"description":"Bad Request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"ValidationError":{"summary":"Validation errors","description":"Indicates that the provided file is empty or has an invalid size. The client must correct the request and retry.","value":{"errors":[{"code":"VALIDATION_ERROR","title":"Invalid Request Parameter","detail":"File size must be greater than 0"}]}}}}}},"401":{"description":"Unauthorized","content":{"application/json":{"examples":{"ErrorResponse":{"description":"Returned when authentication fails due to a missing, invalid, or expired Bearer access token.","value":{"errors":[{"code":"UNAUTHORIZED","title":"Invalid or expired token.","detail":"The provided JWT is invalid or has expired. Please authenticate again and include a valid Bearer token."}]}}}}}},"404":{"description":"Not Found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"ErrorResponse":{"description":"The system was unable to locate the specified client or action item.","value":{"errors":[{"code":"NOT_FOUND","title":"Action Item Not Found","detail":"No action item exists with id '101' for the specified client."}]}}}}}},"500":{"description":"Internal Server Error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"ErrorResponse":{"description":"Represents a generic server failure. The client request was valid, but processing failed due to an internal system error.","value":{"errors":[{"code":"INTERNAL_SERVER_ERROR","title":"Internal server error.","detail":"An unexpected error occurred. Please try again later."}]}}}}}}},"security":[{"apiKey":[]}]}},"/controlmap/v1/clients/action-items-summary":{"get":{"tags":["Action Items"],"summary":"List Client Action Items Summary","description":"Retrieves a paginated summary of action items grouped by client.\n\nSupports filtering, sorting, and cursor-based pagination.\n","operationId":"c_actionitem_1","parameters":[{"name":"filter[client.id]","in":"query","description":"Filters results by client identifier.\n\n**Examples:**\n- `filter[client.id]=eq:365bcf1e-a26b-4abc-ad9a-8607e2f43910`\n- `filter[client.id]=365bcf1e-a26b-4abc-ad9a-8607e2f43910`\n- `filter[client.id]=in:365bcf1e-a26b-4abc-ad9a-8607e2f43910,355bcf1e-a26b-4abc-ad9a-9607e2f43910`\n","schema":{"type":"string"}},{"name":"filter[client.tenant_id]","in":"query","description":"Filters results by tenant identifier.\n\n**Examples:**\n- `filter[client.tenant_id]=eq:Joel Tech`\n- `filter[client.tenant_id]=Joel Tech`\n- `filter[client.tenant_id]=in:leno1,Joel Tech`\n","schema":{"type":"string"}},{"name":"filter[client.name]","in":"query","description":"Filters results by client name (case-insensitive).\n\n**Examples:**\n- `filter[client.name]=eq:lenovo`\n- `filter[client.name]=lenovo`\n- `filter[client.name]=in:lenovo,techno`\n","schema":{"type":"string"}},{"name":"page_size","in":"query","description":"Number of items per page. Default is 50, maximum is 200.","required":false,"schema":{"type":"integer","default":50,"maximum":200,"minimum":1}},{"name":"cursor","in":"query","description":"Opaque cursor used for cursor-based pagination (Base64 encoded).","required":false,"schema":{"type":"string","pattern":"^[A-Za-z0-9+/=]*$"}},{"name":"sort","in":"query","description":"Comma-separated list of fields to sort client summaries.\n\n**Sorting rules:**\n- Ascending: `client.name`, `+client.name`\n- Descending: `-client.name`\n\n**Allowed fields:**\n`client.id`, `client.tenant_id`, `client.name`\n","required":false,"schema":{"type":"string","pattern":"^(?:[+-]|\\s)?(client.id|client.tenant_id|client.name)$"},"example":"client_name,-client.id"}],"responses":{"200":{"description":"Successfully retrieved action items summary","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CursorPaginationResponse"},"examples":{"SuccessResponse":{"summary":"Example successful response","description":"Shows aggregated Action Item summary across clients with pagination.","value":{"data":[{"client":{"id":"365bcf1e-a26b-4abc-ad9a-8607e2f43910","name":"Joel Tech","tenant_id":"joel1"},"action_summary":{"completed":82,"review":0,"in_progress":0,"not_started":2,"not_applicable":0,"total":84,"completion_percentage":97.6}},{"client":{"id":"365bcf1e-a26b-4abc-ad9a-8607e2f43911","name":"Vistel Tech","tenant_id":"joel2"},"action_summary":{"completed":1,"review":0,"in_progress":1,"not_started":128,"not_applicable":0,"total":130,"completion_percentage":0.8}}],"total_count":2,"next_cursor":"eyJpZCI6NDQxLCJwYWdlIjoyfQ=="}}}}}},"400":{"description":"Invalid request parameters","content":{"application/json":{"examples":{"ValidationError_PageSize":{"summary":"Page size exceeds maximum allowed limit","description":"Returned when the request contains invalid pagination","value":{"errors":[{"code":"BAD_REQUEST","title":"Validation error.","detail":"must be less than or equal to 200"}]}},"InvalidSortField":{"summary":"Invalid sort field","description":"Returned when the request contains an invalid or unsupported sort parameter. The client must provide a valid sort field.","value":{"errors":[{"code":"BAD_REQUEST","title":"Validation error.","detail":"Invalid sort field. Valid fields for Asc are: id, code, title, type, status. For Asc add '+' before the field name. For Desc add '-' before the field name."}]}},"InvalidFilterField":{"summary":"Invalid filter field","description":"Returned when the request includes an unsupported or invalid filter field. The client must use a valid, filterable field.","value":{"errors":[{"code":"BAD_REQUEST","title":"Invalid Filter","detail":"Filtering is not supported for the field 'title-new'. Please use a valid filterable field."}]}}}}}},"401":{"description":"Unauthorized – Authentication required","content":{"application/json":{"examples":{"Unauthorized":{"description":"Returned when authentication fails due to a missing, invalid, or expired Bearer access token.","value":{"errors":[{"code":"UNAUTHORIZED","title":"Invalid or expired token.","detail":"The provided JWT is invalid or has expired. Please authenticate again and include a valid Bearer token."}]}}}}}},"500":{"description":"Internal server error","content":{"application/json":{"examples":{"InternalServerError":{"description":"Represents a generic server failure. The client request was valid, but processing failed due to an internal system error.","value":{"errors":[{"code":"INTERNAL_SERVER_ERROR","title":"Internal server error.","detail":"An unexpected error occurred on the server. Please try again later."}]}}}}}}},"security":[{"apiKey":[]}]}},"/controlmap/v1/clients/{client_id}/action-items":{"post":{"tags":["Action Items"],"summary":"Create a new action item","description":"Creates a new action item for the specified client with the provided details\n\n**Allowed values for patchable fields:**\n\n - **status**: `Not Started`, `In Progress`, `Review`, `Completed`, `Not Applicable`\n - **roadmap**: `3 months`, `6 months`, `12 months`\n - **priority**: `High`, `Medium`, `Low`, `Critical`\n - **currency**: `USD`, `EUR`, `AUD`, `CAD`, `SEK`, `NZD`, `SGD`, `INR`\n - **efforts_in_hours**: must be zero or a positive number\n - **cost**: must be zero or a positive number\n","operationId":"createActionItem","parameters":[{"name":"client_id","in":"path","description":"Client ID","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateActionItemRequest"}}},"required":true},"responses":{"201":{"description":"Action item created successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ActionItemResponse"},"examples":{"SuccessResponse":{"description":"Successful response containing details of the newly created action item.","value":{"id":75,"code":"AI-9","entity_code":"ENT-001","parent_entity_id":12,"status":"Not Started","weakness_name":"Implement security patch","weakness_description":"Update all production servers with the latest security patches to address CVE-2023-1234","corrective_action":"Install security updates","responsible_person":"john.doe@example.com","responsible_department":"Sales","efforts":8,"road_map":"3 months","planned_start_date":"2026-03-20","planned_end_date":"2026-04-20","actual_start_date":"2026-03-25","actual_end_date":"2026-04-30","currency":"USD","priority":"High","cost":50,"milestones":"Milestone 1: Planning complete","change_in_milestone":"Extended testing phase by 1 week"}}}}}},"400":{"description":"Bad Request - The request could not be processed due to invalid input","content":{"application/json":{"examples":{"InvalidClientId":{"summary":"Client identifier is invalid","description":"Occurs when the provided clientId does not exist or is not registered in the system.","value":{"errors":[{"code":"INVALID_CLIENT_ID","title":"Invalid Client Identifier","detail":"The provided clientId 'arch434' is invalid or not registered. Please verify the client identifier."}]}},"MissingTitle":{"summary":"Required field 'title' is missing","description":"Occurs when the required field 'title' is not provided in the request payload.","value":{"errors":[{"code":"VALIDATION_ERROR","title":"Invalid Request Parameter","detail":"title: Title is required"}]}},"InvalidResponsiblePerson":{"summary":"Invalid Responsible Person","description":"Occurs when the provided responsible person's email does not exist in the system.","value":{"errors":[{"code":"INVALID_RESPONSIBLE_PERSON","title":"Invalid Responsible Person","detail":"Incorrect Responsible Person, Responsible Person not Exist with email: 'john@exampleValue'"}]}},"InvalidDepartment":{"summary":"Department does not exist","description":"Occurs when the provided department name is not found in the system.","value":{"errors":[{"code":"INVALID_DEPARTMENT","title":"Invalid Department","detail":"Incorrect Department Name, Department not Exist with name: 'exampleValue'"}]}},"InvalidRoadmap":{"summary":"Invalid roadmap value","description":"Occurs when the provided roadmap value is not valid or not supported.","value":{"errors":[{"code":"VALIDATION_ERROR","title":"Invalid Request Parameter","detail":"roadMap: Invalid roadmap"}]}},"InvalidPriority":{"summary":"Invalid priority value","description":"Occurs when the provided priority value is not valid.","value":{"errors":[{"code":"VALIDATION_ERROR","title":"Invalid Request Parameter","detail":"priority: Invalid priority"}]}},"InvalidStatus":{"summary":"Invalid status value","description":"Occurs when the provided status value is not valid.","value":{"errors":[{"code":"VALIDATION_ERROR","title":"Invalid Request Parameter","detail":"status: Invalid status"}]}},"InvalidPlannedStartDate":{"summary":"Invalid planned start date","description":"Occurs when the planned_start_date is not in the expected format (yyyy-MM-dd).","value":{"errors":[{"code":"INVALID_DATE_FORMAT","title":"Invalid Date Format","detail":"planned_Start_date : Invalid date format. Expected format: yyyy-MM-dd"}]}},"InvalidPlannedEndDate":{"summary":"Invalid planned end date","description":"Occurs when the planned_end_date is not in the expected format (yyyy-MM-dd).","value":{"errors":[{"code":"INVALID_DATE_FORMAT","title":"Invalid Date Format","detail":"planned_end_date : Invalid date format. Expected format: yyyy-MM-dd"}]}},"InvalidActualStartDate":{"summary":"Invalid actual start date","description":"Occurs when the actual_start_date is not in the expected format (yyyy-MM-dd).","value":{"errors":[{"code":"INVALID_DATE_FORMAT","title":"Invalid Date Format","detail":"actual_start_date : Invalid date format. Expected format: yyyy-MM-dd"}]}},"InvalidActualEndDate":{"summary":"Invalid actual end date","description":"Occurs when the actual_end_date is not in the expected format (yyyy-MM-dd).","value":{"errors":[{"code":"INVALID_DATE_FORMAT","title":"Invalid Date Format","detail":"actual_end_date : Invalid date format. Expected format: yyyy-MM-dd"}]}},"InvalidCost":{"summary":"Cost value is invalid","description":"Occurs when the cost is negative or not a valid number.","value":{"errors":[{"code":"VALIDATION_ERROR","title":"Invalid Request Parameter","detail":"cost: Cost must be zero or a positive number"}]}},"InvalidCurrency":{"summary":"Invalid currency","description":"Occurs when the provided currency is not supported or invalid.","value":{"errors":[{"code":"VALIDATION_ERROR","title":"Invalid Request Parameter","detail":"currency: Invalid currency"}]}}}}}},"401":{"description":"Unauthorized","content":{"application/json":{"examples":{"ErrorResponse":{"description":"Returned when authentication fails due to a missing, invalid, or expired Bearer access token.","value":{"errors":[{"code":"UNAUTHORIZED","title":"Invalid or expired token.","detail":"The provided JWT is invalid or has expired. Please authenticate again and include a valid Bearer token."}]}}}}}},"500":{"description":"Internal Server Error","content":{"application/json":{"examples":{"ErrorResponse":{"description":"Represents a generic server failure. The client request was valid, but processing failed due to an internal system error.","value":{"errors":[{"code":"INTERNAL_SERVER_ERROR","title":"Internal server error.","detail":"An unexpected error occurred on the server. Please try again later."}]}}}}}}},"security":[{"apiKey":[]}]}},"/controlmap/v1/clients/{client_id}/action-items/{action_item_id}/documents/signed-url":{"post":{"tags":["Action Items"],"summary":"Generate Signed URLs to Upload Documents for an Action Item","description":"Generates pre-signed URL(s) to upload document(s) for the specified action item.\n\nThe client uploads files directly to S3 using the returned signed_url\nbefore expires_in_seconds elapses.\n","operationId":"d_actionitem","parameters":[{"name":"client_id","in":"path","description":"Unique identifier for the client (ControlMap tenant or client ID).","required":true,"schema":{"type":"string","format":"uuid","example":"365bcf1e-a26b-4abc-ad9a-8607e2f43910"}},{"name":"action_item_id","in":"path","description":"ID of the action item.","required":true,"schema":{"type":"integer","example":101}}],"requestBody":{"description":"List of documents to upload (file name and size in bytes).","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/EvidenceUploadRequest"}},"examples":{"GenerateSignedUrlsRequest":{"summary":"Generate signed URLs for multiple documents","description":"Request payload containing file names and sizes to generate pre-signed URLs for direct document upload.","value":[{"file_name":"Action_Item_Evidence_Q1_2026.pdf","file_size_bytes":245760},{"file_name":"Incident_Snapshot_2026-02-12.png","file_size_bytes":102400}]}}}},"required":true},"responses":{"201":{"description":"Ok","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DocumentUploadResponse"},"examples":{"DocumentUploadResponse":{"summary":"Response containing signed URLs for upload","description":"Response containing document details and pre-signed URLs for secure, direct file upload with expiration time.","value":{"id":"101","code":"AI-9","documents":[{"file_name":"Action_Item_Evidence_Q1_2026.pdf","document_id":501,"signed_url":"https://s3....","expires_in_seconds":300},{"file_name":"Incident_Snapshot_2026-02-12.png","document_id":502,"signed_url":"https://s3....","expires_in_seconds":300}]}}}}}},"400":{"description":"Bad Request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"ValidationError":{"summary":"Validation errors","description":"Indicates that one or more request parameters are invalid or violates business validation rules. The client must correct the request and retry.","value":{"errors":[{"code":"VALIDATION_ERROR","title":"Invalid Request Parameter","detail":"File size must be greater than 0"}]}}}}}},"401":{"description":"Unauthorized","content":{"application/json":{"examples":{"ErrorResponse":{"description":"Returned when authentication fails due to a missing, invalid, or expired Bearer access token.","value":{"errors":[{"code":"UNAUTHORIZED","title":"Invalid or expired token.","detail":"The provided JWT is invalid or has expired. Please authenticate again and include a valid Bearer token."}]}}}}}},"404":{"description":"Not Found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"ErrorResponse":{"description":"The system was unable to locate the specified client or tenant, or no action item exists for the provided ID.","value":{"errors":[{"code":"NOT_FOUND","title":"Action Item Not Found","detail":"No action item exists with id '101' for the specified client."}]}}}}}},"500":{"description":"Internal Server Error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"ErrorResponse":{"description":"Represents a generic server failure. The client request was valid, but processing failed due to an internal system error.","value":{"errors":[{"code":"INTERNAL_SERVER_ERROR","title":"Internal server error.","detail":"An unexpected error occurred. Please try again later."}]}}}}}}},"security":[{"apiKey":[]}]}},"/controlmap/v1/clients/{client_id}/frameworks/objectives/summary":{"get":{"tags":["Frameworks"],"summary":"Client Objective Summary","description":"Returns Objective summary for a single client.\n\n","operationId":"getClientRequirementsObjectiveSummary","parameters":[{"name":"client_id","in":"path","description":"Unique identifier of the client whose Objectives are being retrieved.","required":true,"schema":{"type":"string"},"example":"365bcf1e-a26b-4abc-ad9a-8607e2f43910"}],"responses":{"200":{"description":"SuccessResponse","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ClientObjectiveSummaryResponse"},"examples":{"SuccessResponse":{"description":"Shows aggregated Objectives summary for a client.","value":{"client":{"id":"365bcf1e-a26b-4abc-ad9a-8607e2f43910","name":"Joel Tech","tenant_id":"joel1"},"framework_stats":[{"id":3,"name":"ISO-27001","objective_summary":{"compliant":0,"not_compliant":0,"partially_compliant":0,"not_assessed":61,"in_review":0,"not_applicable":19,"total":121,"complaint_percentage":13}},{"id":4,"name":"NIST CSF 2.0","objective_summary":{"compliant":0,"not_compliant":0,"partially_compliant":0,"not_assessed":50,"in_review":0,"not_applicable":13,"total":93,"complaint_percentage":12}}]}}}}}},"401":{"description":"Unauthorized - Authentication required","content":{"application/json":{"examples":{"ErrorResponse":{"description":"Returned when authentication fails due to a missing, invalid, or expired Bearer access token.","value":{"errors":[{"code":"UNAUTHORIZED","title":"Invalid or expired token.","detail":"The provided JWT is invalid or has expired. Please authenticate again and include a valid Bearer token."}]}}}}}},"404":{"description":"Resource Not Found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"ErrorResponse":{"description":"The requested client or tenant was not found, or the API path/version is invalid or unsupported.","value":{"errors":[{"code":"NOT_FOUND","title":"Resource Not Found","detail":"The requested resource could not be found. Please verify the API path and version."}]}}}}}},"500":{"description":"Internal Server Error","content":{"application/json":{"examples":{"ErrorResponse":{"description":"Represents a generic server failure. The client request was valid, but processing failed due to an internal system error.","value":{"errors":[{"code":"INTERNAL_SERVER_ERROR","title":"Internal server error.","detail":"An unexpected error occurred on the server. Please try again later."}]}}}}}}},"security":[{"apiKey":[]}]}},"/controlmap/v1/clients/{client_id}/reports/{report_id}/signed-url":{"get":{"tags":["Reports"],"summary":"Retrieve a signed URL to download a report","description":"Returns metadata for a specific report document and a secure, time-limited\npre-signed URL for downloading the file.\n\nThe signed URL expires after the specified number of seconds and must be used\nbefore that time. This endpoint ensures secure access to stored report files\nwithout exposing them publicly.\n\n**Response includes:**\n- `id`               — unique document identifier\n- `name`             — human-readable report title\n- `signed_url`        — downloadable, pre-signed URL\n- `expires_in_seconds` — time remaining before the URL expires\n","operationId":"getReportSignedUrl","parameters":[{"name":"client_id","in":"path","description":"Unique identifier of the client for whom risks are being retrieved.","required":true,"schema":{"type":"string"},"example":"365bcf1e-a26b-4abc-ad9a-8607e2f43910"},{"name":"report_id","in":"path","description":"Unique identifier of the report document.","required":true,"schema":{"type":"integer"},"example":1234}],"responses":{"200":{"description":"OK — Signed URL and metadata returned successfully.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReportDocumentResponse"},"examples":{"ReportDocumentResponse":{"summary":"Signed URL response example","description":"Response containing report document metadata and a pre-signed URL with expiration time.","value":{"id":1234,"name":"Compliance Health Report","signed_url":"https://bucket.s3.amazonaws.com/report.pdf?X-Amz-Signature=...","expires_in_seconds":3600}}}}}},"400":{"description":"Bad Request — Invalid request parameters or malformed path inputs.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"ErrorResponse":{"summary":"Invalid path or request values","description":"Indicates that one or more request parameters are invalid or violates business validation rules. The client must correct the request and retry.","value":{"errors":[{"code":"INVALID_CLIENT","title":"Invalid client identifier.","detail":"The clientId 'leno34' is invalid or not registered. Please verify the client ID in the request path."}]}}}}}},"401":{"description":"Unauthorized - Authentication required","content":{"application/json":{"examples":{"ErrorResponse":{"description":"Returned when authentication fails due to a missing, invalid, or expired Bearer access token.","value":{"errors":[{"code":"UNAUTHORIZED","title":"Invalid or expired token.","detail":"The provided JWT is invalid or has expired. Please authenticate again and include a valid Bearer token."}]}}}}}},"404":{"description":"Not Found — The client or report document does not exist.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"ErrorResponse":{"description":"The system was unable to locate the specified client or tenant, or no report exists for the provided report ID.","value":{"errors":[{"code":"NOT_FOUND","title":"Not Found","detail":"We couldn’t find the requested report. Please check the ID and try again."}]}}}}}},"500":{"description":"Server Error — Unexpected error occurred while generating the signed URL.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"ErrorResponse":{"description":"Represents a generic server failure. The client request was valid, but processing failed due to an internal system error.","value":{"errors":[{"code":"INTERNAL_SERVER_ERROR","title":"Internal server error.","detail":"An unexpected error occurred on the server. Please try again later."}]}}}}}}},"security":[{"apiKey":[]}]}},"/controlmap/v1/clients/frameworks/objectives/summary":{"get":{"tags":["Frameworks"],"summary":"Clients Objective Overview","description":"Returns paginated Objective summaries for all partner clients.\n\nThis endpoint supports:\n- Cursor-based pagination\n- Sorting\n- Filtering\n\n**Use Cases:**\n- Retrieve Objective summaries across all MSP clients\n- Build partner-level dashboards\n- Analyze Objective completeness across multiple tenants\n- Paginate large Objective summary datasets\n","operationId":"getRequirementsObjectiveSummary","parameters":[{"name":"filter[client.tenant_id]","in":"query","description":"Filters records by the `client.tenant_id` field.\n\n**Supported operators:**\n- `eq` — exact match\n- `in` — list-based match\n\n**Examples:**\n- `filter[client.tenant_id]=Joel Tech` — to filter for exact match\n- `filter[client.tenant_id]=eq:Joel Tech` — to filter for exact match\n- `filter[client.tenant_id]=in:Joel Tech,John Tech` — to filter for any match in list\n","schema":{"type":"string"},"example":"eq:Joel Tech"},{"name":"filter[client.name]","in":"query","description":"Filters records by the `client.name` field.\n\n**Supported operators:**\n- `eq` — exact match\n- `in` — list-based match\n\n**Examples:**\n- `filter[client.name]=Joel King` — to filter for exact match\n- `filter[client.name]=eq:Joel King` — to filter for exact match\n- `filter[client.name]=in:Joel King,John` — to filter for any match in list\n","schema":{"type":"string"},"example":"eq:Joel King"},{"name":"page_size","in":"query","description":"Number of records to return per page.\nMust be between **1 and 200**.\nDefault: **50**\n","required":false,"schema":{"type":"integer","format":"int32","default":50,"maximum":200,"minimum":1},"example":50},{"name":"cursor","in":"query","description":"Base64-encoded cursor value used for pagination.\nPass the cursor received from the previous response to fetch the next page.\n","required":false,"schema":{"type":"string","pattern":"^[A-Za-z0-9+/=]*$"},"example":"eyJpZCI6NDQxLCJwYWdlIjoxfQ=="},{"name":"sort","in":"query","description":"Single sort field (comma-separated lists are not accepted by this endpoint).\n\nPrefix with `-` for descending. Optional `+` prefix or no prefix means ascending.\n\n**Allowed values:** `client.name`, `client.tenant_id`\n","required":false,"schema":{"type":"string","pattern":"^(?:[+-]|\\s)?(client.tenant_id|client.name)$"},"example":"client.name"}],"responses":{"200":{"description":"SuccessResponse","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/ClientObjectiveSummaryResponse"}},"examples":{"SuccessResponse":{"description":"Shows aggregated Objectives summary across clients.","value":{"data":[{"client":{"id":"365bcf1e-a26b-4abc-ad9a-8607e2f43910","name":"Joel Tech","tenant_id":"joel1"},"framework_stats":[{"id":3,"name":"ISO-27001","objective_summary":{"compliant":0,"not_compliant":0,"partially_compliant":0,"not_assessed":61,"in_review":0,"not_applicable":19,"total":121,"complaint_percentage":0}},{"id":4,"name":"NIST CSF 2.0","objective_summary":{"compliant":0,"not_compliant":0,"partially_compliant":0,"not_assessed":50,"in_review":0,"not_applicable":13,"total":93,"complaint_percentage":0}}]},{"client":{"id":"365bcf1e-a26b-4abc-ad9a-2507e2f43911","name":"Vistel Tech","tenant_id":"vistel2"},"framework_stats":[{"id":2,"name":"CYBERSECURITY MATURITY MODEL CERTIFICATION (CMMC 2.0)","objective_summary":{"compliant":0,"not_compliant":0,"partially_compliant":0,"not_assessed":66,"in_review":0,"not_applicable":44,"total":66,"complaint_percentage":0}}]}]}}}}}},"400":{"description":"Bad Request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"validationError":{"summary":"Invalid query parameter or operator","description":"Returned when the request contains an invalid filter parameter or an unsupported query operator.","value":{"errors":[{"code":"VALIDATION_ERROR","title":"Invalid Query Parameter","detail":"Invalid filter or unsupported operator."}]}},"invalidSortField":{"summary":"Invalid sort field","description":"Returned when the request contains an invalid or unsupported sort parameter. The client must provide a valid sort field.","value":{"errors":[{"code":"BAD_REQUEST","title":"Validation error.","detail":"Allowed fields:client.tenant_id, client.name. Use '-' for descending, '+' or no prefix for ascending."}]}},"invalidFilterField":{"summary":"Invalid filter field","description":"Returned when the request includes an unsupported or invalid filter field. The client must use a valid, filterable field.","value":{"errors":[{"code":"BAD_REQUEST","title":"Invalid Filter","detail":"Filtering is not supported for the field 'abc'. Please use a valid filterable field."}]}}}}}},"401":{"description":"Unauthorized - Authentication required","content":{"application/json":{"examples":{"ErrorResponse":{"description":"Returned when authentication fails due to a missing, invalid, or expired Bearer access token.","value":{"errors":[{"code":"UNAUTHORIZED","title":"Invalid or expired token.","detail":"The provided JWT is invalid or has expired. Please authenticate again and include a valid Bearer token."}]}}}}}},"500":{"description":"Internal Server Error","content":{"application/json":{"examples":{"ErrorResponse":{"description":"Represents a generic server failure. The client request was valid, but processing failed due to an internal system error.","value":{"errors":[{"code":"INTERNAL_SERVER_ERROR","title":"Internal server error.","detail":"An unexpected error occurred on the server. Please try again later."}]}}}}}}},"security":[{"apiKey":[]}]}}},"components":{"schemas":{"AssessmentAnswerPutRequest":{"type":"object","description":"Submit or update the assessment question answer. Use DELETE on the same path to clear the answer.","properties":{"answer":{"type":"string","description":"Selected answer label (must match a valid option for the question).","enum":["Yes","No","Partially","NA"],"example":"Yes","minLength":1,"pattern":"^(Yes|No|Partially|NA)$"}},"required":["answer"]},"AssessmentAnswerResponse":{"type":"object","description":"Assessment answer save response with minimal fields","properties":{"question_code":{"type":"string","description":"Question code"},"answer":{"type":"string","description":"Selected answer","example":"Yes"},"answered_by":{"$ref":"#/components/schemas/UserMetadata","description":"User who submitted the answer"},"reset_answer":{"type":"boolean","description":"Whether answer was reset"},"answered_at":{"type":"string","description":"Date when answer was submitted (yyyy-MM-dd)","example":"2025-09-15"}}},"UserMetadata":{"type":"object","description":"User metadata including id, full name, and email","properties":{"id":{"type":"integer","format":"int32","description":"User ID","example":22},"name":{"type":"string","description":"User full name","example":"John Doe"},"email":{"type":"string","description":"User email address","example":"john.doe@example.com"}}},"ErrorDetail":{"type":"object","properties":{"code":{"type":"string"},"title":{"type":"string"},"detail":{"type":"string"}}},"ErrorResponse":{"type":"object","description":"Standard error response format for API errors","properties":{"errors":{"type":"array","items":{"$ref":"#/components/schemas/ErrorDetail"}}}},"RiskQueryRequest":{"type":"object","description":"Query request for risks with filters, fields, pagination, cursor, and sort","properties":{"filter":{"type":"object","additionalProperties":{"type":"string"}},"fields":{"type":"string"},"page_size":{"type":"integer","format":"int32","maximum":200,"minimum":1},"cursor":{"type":"string","pattern":"^[A-Za-z0-9+/=]*$"},"sort":{"type":"string","pattern":"^[+\\-\\s]?(id|name|current_risk|owner\\.name)$"}}},"RiskResponse":{"type":"object","description":"Risk entity response containing metadata, ownership, scoring details and timestamps","properties":{"id":{"type":"integer","format":"int32","description":"Unique identifier for the risk record"},"code":{"type":"string","description":"Unique risk code used internally or externally to identify the risk"},"name":{"type":"string","description":"Risk title or short name describing the risk"},"description":{"type":"string","description":"Detailed explanation of what the risk is about"},"owner":{"$ref":"#/components/schemas/UserMetadata","description":"Owner of the risk including metadata such as ID and display name"},"status":{"type":"string","description":"Current status of the risk (e.g., 'Not Assessed', 'Assessment in progress', or 'closed')"},"department":{"type":"string","description":"Department associated with this risk (e.g., Finance, IT, Security)"},"risk_category":{"type":"string","description":"Risk category or classification (e.g., Operational, Compliance, Strategic)"},"treatment":{"type":"string","description":"Treatment plan for the risk (e.g., Accept, Avoid, Transfer)"},"business_impact":{"type":"string","description":"The potential impact of the risk on the business operations or objectives"},"created_by":{"$ref":"#/components/schemas/UserMetadata","description":"User who created this risk entry"},"inherent_risk_score":{"type":"integer","format":"int32","description":"Inherent risk score assessed before any controls are applied"},"inherent_risk_label":{"type":"string","description":"Inherent risk score label, such as 'Low', 'Medium', or 'High', based on the Inherent risk score value"},"current_risk_score":{"type":"integer","format":"int32","description":"Current risk score assessed after applying controls"},"current_risk_label":{"type":"string","description":"Current risk score label, such as 'Low', 'Medium', or 'High', based on the Current risk score value"},"target_risk_score":{"type":"integer","format":"int32","description":"Target risk score assessed representing planned/expected state"},"target_risk_label":{"type":"string","description":"Target risk score label, such as 'Low', 'Medium', or 'High', based on the Target risk score value"},"created_at":{"type":"string","format":"date-time","description":"Timestamp when the risk was created (ISO 8601 format)","example":"2025-09-15T17:00:00Z"},"updated_at":{"type":"string","format":"date-time","description":"Timestamp when the risk was last updated (ISO 8601 format)","example":"2025-09-15T17:00:00Z"}},"required":["code","created_at","created_by","id","name","status","updated_at"]},"ReportQueryRequest":{"type":"object","description":"Query request for reports with filters, fields, pagination, cursor, and sort","properties":{"filter":{"type":"object","additionalProperties":{"type":"string"}},"fields":{"type":"string"},"page_size":{"type":"integer","format":"int32","maximum":200,"minimum":1},"cursor":{"type":"string","pattern":"^[A-Za-z0-9+/=]*$"},"sort":{"type":"string","description":"Sorting field","example":"+created_at","pattern":"^(?:[+-]|\\s)?(created_at|report_name|status)$"}}},"Client":{"type":"object","description":"Client Metadata","properties":{"id":{"type":"string","description":"Unique identifier for the client (external client ID)","example":"08b538f9-4e59-4bc2-9b13-7df755e06c4f"},"name":{"type":"string","description":"Name of the client organization","example":"ABC Corporation"},"tenant_id":{"type":"string","description":"Internal ControlMap tenant identifier","example":"abctech"}}},"ClientReportPaginatedResponse":{"type":"object","description":"API response containing client details and paginated list of reports","properties":{"client":{"$ref":"#/components/schemas/Client","description":"Client metadata"},"report_summary":{"$ref":"#/components/schemas/ReportSummary","description":"Overall summary of reports for the client"},"reports":{"$ref":"#/components/schemas/ReportPaginatedResponse","description":"Paginated list of reports for this client"}}},"ReportPaginatedResponse":{"type":"object","description":"Paginated response for reports","properties":{"total_count":{"type":"integer","format":"int64","description":"Total number of reports for the client"},"next_cursor":{"type":"string","description":"Cursor for fetching next set of items"},"data":{"type":"array","description":"List of reports for this page","items":{"$ref":"#/components/schemas/ReportResponse"}}}},"ReportResponse":{"type":"object","description":"Report entity response containing metadata, created by and timestamps","properties":{"id":{"type":"integer","format":"int32","description":"Unique identifier for the report record"},"report_name":{"type":"string","description":"Report title"},"program":{"type":"string","description":"Name of the program whose data is included in this report"},"created_by":{"$ref":"#/components/schemas/UserMetadata","description":"User who created this report"},"created_at":{"type":"string","format":"date-time","description":"Timestamp when the report was created (ISO 8601 format)"},"status":{"type":"string","description":"Current generation status of the report (e.g., 'Completed', 'Progress', 'Fail')"}}},"ReportSummary":{"type":"object","description":"Summary of report statuses for the client","properties":{"total":{"type":"integer","format":"int64","description":"Total number of reports associated with the client","example":42},"progress":{"type":"integer","format":"int64","description":"Number of reports currently in progress","example":75},"completed":{"type":"integer","format":"int64","description":"Number of reports successfully completed","example":30},"failed":{"type":"integer","format":"int64","description":"Number of reports that have failed","example":12}}},"EvidenceRequestResponse":{"type":"object","description":"Response object containing detailed information about an Evidence Request","properties":{"id":{"type":"integer","format":"int32","description":"Unique identifier of the evidence request","example":145},"code":{"type":"string","description":"Code representing the evidence request","example":"EV-20-1"},"title":{"type":"string","description":"Title of the evidence request"},"description":{"type":"string","description":"Description of the evidence request"},"status":{"type":"string","description":"Current status of the evidence request","example":"In Progress"},"created_by":{"$ref":"#/components/schemas/UserMetadata","description":"User who created this evidence request"},"owner":{"$ref":"#/components/schemas/UserMetadata","description":"User currently assigned as the owner of the evidence request"},"documents":{"type":"array","description":"List of uploaded documents with pre-signed URLs","items":{"$ref":"#/components/schemas/PresignedUrlResponse"}},"due_date":{"type":"string","format":"date-time","description":"Due date for completing this evidence request (ISO timestamp)","example":"2025-12-16T10:30:00"},"updated_at":{"type":"string","format":"date-time","description":"Timestamp when the evidence request was last updated","example":"2025-12-02T14:22:10"},"created_at":{"type":"string","format":"date-time","description":"Timestamp when the evidence request was created","example":"2025-12-01T09:05:00"},"implementation_notes":{"type":"string","description":"Additional implementation notes or comments for this evidence request"}}},"EvidenceResponse":{"type":"object","description":"Detailed response containing evidence metadata, requests, owners and timestamps.","properties":{"id":{"type":"integer","format":"int32","description":"Unique identifier of the evidence","example":301},"code":{"type":"string","description":"Unique evidence code generated by the system","example":"EV-2025-001"},"title":{"type":"string","description":"Title or short name of the evidence","example":"SOC 2 Access Review Evidence"},"description":{"type":"string","description":"Optional description providing additional context for the evidence","example":"Quarterly SOC 2 evidence related to access reviews and user provisioning."},"repeats":{"type":"boolean","description":"Indicates whether this evidence is recurring","example":false},"evidence_requests":{"type":"array","description":"List of evidence requests associated with this evidence item","items":{"$ref":"#/components/schemas/EvidenceRequestResponse"},"uniqueItems":true},"evidence_request_summary":{"type":"object","additionalProperties":{"type":"integer","format":"int64"},"description":"Summary of evidence requests grouped by status. Example: { 'completed': 4, 'review': 2, 'in_progress': 0 , 'not_started': 2 , 'not_applicable': 0 , 'total': 6  }","example":"{ \"completed\": 4, \"review\": 2, , \"in_progress\": 0 , 'not_started': 2, 'not_applicable': 0 , 'total': 6  }"},"created_by":{"$ref":"#/components/schemas/UserMetadata","description":"User who created this evidence"},"owner":{"$ref":"#/components/schemas/UserMetadata","description":"User who currently owns this evidence"},"schedule":{"type":"string","description":"Schedule information for recurring evidence, if applicable","example":"Quarterly on the first Monday"},"refresh_status":{"type":"string","description":"Evidence freshness status based on most recent completion date","example":"Current"},"updated_date":{"type":"string","format":"date-time","description":"Timestamp when this evidence was last updated","example":"2025-12-02T14:22:10"},"created_date":{"type":"string","format":"date-time","description":"Timestamp when this evidence was created","example":"2025-12-01T09:05:00"}}},"PresignedUrlResponse":{"type":"object","description":"Represents a document with a pre-signed URL for download","properties":{"id":{"type":"integer","format":"int32","description":"Document ID","example":501},"file_name":{"type":"string","description":"Name of the uploaded document","example":"policy.pdf"},"presigned_url":{"type":"string","description":"Pre-signed URL for downloading the document"},"last_update":{"type":"string","format":"date-time","description":"Timestamp when the document was last updated","example":"2025-12-01T09:55:11"}}},"EvidenceUploadRequest":{"type":"object","properties":{"file_name":{"type":"string"},"file_size_bytes":{"type":"integer","format":"int32"}}},"EvidenceUploadResponse":{"type":"object","properties":{"file_name":{"type":"string"},"document_id":{"type":"integer","format":"int32"},"method":{"type":"string"},"signed_url":{"type":"string"},"expires_in_seconds":{"type":"integer","format":"int32"}}},"SignedUploadResponse":{"type":"object","properties":{"evidence_request_id":{"type":"integer","format":"int32"},"evidence_request_code":{"type":"string"},"documents":{"type":"array","items":{"$ref":"#/components/schemas/EvidenceUploadResponse"}}}},"EvidenceQueryRequest":{"type":"object","description":"Query request for evidences with filters, fields, pagination, cursor, and sort","properties":{"filter":{"type":"object","additionalProperties":{"type":"string"}},"fields":{"type":"string"},"page_size":{"type":"integer","format":"int32","maximum":200,"minimum":1},"cursor":{"type":"string","pattern":"^[A-Za-z0-9+/=]*$"},"fetch_items":{"type":"boolean","default":"true","description":"Include related evidence items"},"evidence_request":{"type":"boolean","default":"true","description":"Include evidence requests"},"sort":{"type":"string","description":"Sorting field","example":"+created_at","pattern":"^(?:[+-]|\\s)?(created_at|updated_at)$"}}},"ClientEvidencePaginatedResponse":{"type":"object","description":"API response containing client details and paginated list of evidences","properties":{"client":{"$ref":"#/components/schemas/Client","description":"Client metadata"},"evidence_summary":{"$ref":"#/components/schemas/EvidenceProgress"},"evidences":{"$ref":"#/components/schemas/EvidencePaginatedResponse","description":"Paginated list of evidences for this client"}}},"EvidencePaginatedResponse":{"type":"object","description":"Paginated response for evidences list","properties":{"data":{"type":"array","description":"List of evidences for this page","items":{"$ref":"#/components/schemas/EvidenceRequestResponse"}},"total_count":{"type":"integer","format":"int64","description":"Total number of evidences for the client"},"next_cursor":{"type":"string","description":"Cursor for fetching next set of items"}}},"EvidenceProgress":{"type":"object","description":"Progress tracking information for Evidence","properties":{"completed":{"type":"integer","format":"int32","description":"Number of evidence 'Completed'"},"review":{"type":"integer","format":"int32","description":"Number of evidence in 'Review'"},"in_progress":{"type":"integer","format":"int32","description":"Number of evidence in 'In Progress'"},"not_started":{"type":"integer","format":"int32","description":"Number of evidence 'Not Started'"},"not_applicable":{"type":"integer","format":"int32","description":"Number of evidence 'Not Applicable'"},"total":{"type":"integer","format":"int32","description":"Total Evidences"},"completion_percentage":{"type":"number","format":"float","description":"Evidence Completion Percentage"}}},"CreateEvidenceRequest":{"type":"object","description":"Request payload for creating a new Evidence","properties":{"title":{"type":"string","description":"Title of the evidence","example":"SOC 2 Access Review Evidence","minLength":1},"description":{"type":"string","description":"Description of the Evidence","example":"Quarterly user access review evidence for SOC 2 audit."},"owner_email":{"type":"string","description":"Email address of the evidence owner","example":"john.doe@example.com"},"assignee_email":{"type":"string","description":"User assigned to this evidence","example":"john.doe@example.com"},"repeat_type":{"type":"string","default":"once","description":"Defines how often the evidence is updated.","enum":["once","recurring"],"example":"once","pattern":"once|recurring"},"schedule":{"$ref":"#/components/schemas/EvidenceSchedule","description":"Recurring evidence schedule"}}},"EvidenceSchedule":{"type":"object","description":"Defines recurrence schedule details for an Evidence","properties":{"frequency":{"type":"string","description":"Frequency at which the evidence repeats.","enum":["WEEKLY","MONTHLY","YEARLY"],"example":"WEEKLY","pattern":"weekly|monthly|yearly"},"interval":{"type":"integer","format":"int32","default":"1","description":"Interval at which the evidence repeats. For example, every 1 week or every 2 months.","example":1,"minimum":1},"days_of_week":{"type":"array","description":"Days of the week when frequency is WEEKLY. If not provided, it defaults to the day on which the schedule is created.","example":["MONDAY","FRIDAY"],"items":{"type":"string","pattern":"monday|tuesday|wednesday|thursday|friday|saturday|sunday"}},"day_of_month":{"type":"integer","format":"int32","default":"1","description":"Day of the month when frequency is MONTHLY.","example":1,"maximum":31,"minimum":1},"start_date":{"type":"string","format":"date","description":"Date when the schedule starts.","example":"2025-01-01"},"end_type":{"type":"string","default":"after_occurrences","description":"Defines when the schedule ends.","enum":["on_date","after_occurrences"],"example":"after_occurrences","pattern":"on_date|after_occurrences"},"end_date":{"type":"string","format":"date","description":"End date of the schedule. Required when endType is ON_DATE.","example":"2025-12-31"},"occurrences":{"type":"integer","format":"int32","default":"1","description":"Number of occurrences after which the schedule ends. Required when endType is AFTER_OCCURRENCES.","example":10,"minimum":1}},"required":["end_type","frequency","start_date"]},"CmapResponse":{"type":"object","properties":{"id":{"type":"integer","format":"int32"},"code":{"type":"integer","format":"int32"},"message":{"type":"string"},"entity":{"type":"string"},"entityCode":{"type":"string"},"mappedEntityCode":{"type":"string"},"title":{"type":"string"},"attributeName":{"type":"string"},"oldValue":{"type":"string"},"newValue":{"type":"string"},"entityid":{"type":"integer","format":"int32"},"entityIds":{"type":"array","items":{"type":"integer","format":"int32"}},"eventId":{"type":"string"},"parentEntityId":{"type":"integer","format":"int32"},"status":{"type":"boolean"},"errorMap":{"type":"object","additionalProperties":{"type":"array","items":{"type":"string"}}},"count":{"type":"integer","format":"int32"},"additionalData":{"type":"object","additionalProperties":{"type":"object"}}}},"EvidenceLinkCreateRequest":{"type":"object","description":"Request payload for creating a new link associated with an Evidence request","properties":{"evidence_request_id":{"type":"integer","format":"int32","description":"Unique identifier for evidence request","example":102},"name":{"type":"string","description":"Display name for the link","example":"SOC 2 Evidence Folder","minLength":1},"hyperlink":{"type":"string","description":"Valid external URL pointing to the evidence resource","example":"https://drive.google.com/folder/12345","maxLength":2000,"minLength":0}},"required":["evidence_request_id"]},"ClientRequirementSearchRequest":{"type":"object","description":"Query request for requirements with filters, fields, pagination, cursor, and sort","properties":{"filter":{"type":"object","additionalProperties":{"type":"string"}},"fields":{"type":"string"},"page_size":{"type":"integer","format":"int32","maximum":200,"minimum":1},"cursor":{"type":"string","pattern":"^[A-Za-z0-9+/=]*$"},"sort":{"type":"string","pattern":"^$|^[+\\-\\s]?(id|name|req_id|sort_order)$"}}},"ClientRequirementSearchResponse":{"type":"object","description":"API response containing client details and paginated list of requirements","properties":{"client":{"$ref":"#/components/schemas/Client","description":"Client metadata"},"framework":{"$ref":"#/components/schemas/Framework"},"objective_summary":{"$ref":"#/components/schemas/ObjectiveSummary"},"objectives":{"$ref":"#/components/schemas/RequirementPaginatedResponse","description":"Paginated list of objectives for this client"}}},"Entity":{"type":"object","description":"Referenced entity","properties":{"id":{"type":"integer","format":"int32","description":"Entity identifier","example":42},"name":{"type":"string","description":"Entity display name","example":"Acme Corp"},"code":{"type":"string","description":"Entity code","example":"ACM"}}},"Framework":{"type":"object","description":"Compliance score for a specific compliance framework","properties":{"framework_id":{"type":"string","description":"Unique identifier for the compliance framework (e.g., 'soc2', 'iso27001')"},"framework_name":{"type":"string","description":"Human-readable name of the compliance framework (e.g., 'SOC 2', 'ISO 27001')"},"compliance_score":{"type":"number","format":"float","description":"Compliance score for this specific framework (0-10 scale)"},"score_label":{"type":"string","description":"Human-readable label for the framework score (e.g., 'Excellent', 'Good', 'Average', 'Poor')"},"updated_at":{"type":"string","format":"date-time","description":"ISO 8601 timestamp when this client's health data was last updated","example":"2025-09-15T17:00:00Z"},"compliance_breakdown":{"$ref":"#/components/schemas/ComplianceBreakdown"},"assessment_breakdown":{"$ref":"#/components/schemas/AssessmentBreakdown"}}},"Objective":{"type":"object","description":"objective (id, reqid, name, program)","properties":{"id":{"type":"integer","format":"int32"},"code":{"type":"string"},"name":{"type":"string"},"program_name":{"type":"string"}}},"ObjectiveSummary":{"type":"object","description":"Overall objective completion metrics based on the framework for a client tenant.","properties":{"compliant":{"type":"integer","format":"int32","description":"The number/count of responses marked as 'Compliant'"},"not_compliant":{"type":"integer","format":"int32","description":"The number/count of responses marked as 'Not Compliant'"},"partially_compliant":{"type":"integer","format":"int32","description":"The number/count of responses marked as 'Partially Compliant'"},"not_assessed":{"type":"integer","format":"int32","description":"The number/count of responses marked as 'Not Assessed'"},"in_review":{"type":"integer","format":"int32","description":"The number/count of responses marked as 'In Review'"},"not_applicable":{"type":"integer","format":"int32","description":"The number/count of responses marked as 'Not Applicable'"},"total":{"type":"integer","format":"int32","description":"Total Objectives"},"compliance_percentage":{"type":"integer","format":"int32","description":"Compliance Percentage"}}},"RequirementPaginatedResponse":{"type":"object","description":"Paginated response for requirement list","properties":{"total_count":{"type":"integer","format":"int64","description":"Total number of requirements matching the filter for the client"},"next_cursor":{"type":"string","description":"Cursor for fetching next set of items"},"data":{"type":"array","description":"List of requirements for this page","items":{"$ref":"#/components/schemas/Objective"}}}},"AssessmentQuestionResponseCreateRequest":{"type":"object","description":"Create a new response note on an assessment question (snake_case JSON: `response`, `provided_by`).","properties":{"response":{"type":"string","description":"Response body text","example":"Auditor follow-up: evidence received.","minLength":1},"provided_by":{"type":"string","description":"Display name for who provided the note; defaults to the authenticated user's name when omitted"}},"required":["response"]},"AssessmentQuestionNoteResponse":{"type":"object","description":"Persisted assessment question response note (snake_case JSON).","properties":{"id":{"type":"integer","format":"int32","description":"Note row id"},"question_id":{"type":"integer","format":"int32","description":"Assessment question id"},"question_code":{"type":"string","description":"Assessment question code"},"response":{"type":"string","description":"Note text"},"provided_by":{"type":"string","description":"Captured provider display name (`provided_by` column)"},"created_at":{"type":"string","format":"date-time","description":"When the note was created (ISO 8601)","example":"2026-03-27"},"updated_at":{"type":"string","format":"date-time","description":"When the note was last updated (ISO 8601)","example":"2026-03-27"},"created_by":{"$ref":"#/components/schemas/Owner","description":"User who captured the note (when available)"}}},"Owner":{"type":"object","description":"owner/user (id, full_name, email only)","properties":{"id":{"type":"integer","format":"int32"},"full_name":{"type":"string"},"email":{"type":"string"}}},"AssessmentQuestionMapRequest":{"type":"object","description":"Business codes resolved server-side to internal ids:\nevidence_codes → task_def.code → task_def.id stored as EVIDENCE on assessment_question_mapping (same as legacy evidence/task-def linking);\naction_item_codes → task_def.code → task_def.id for Action Item mappings;\nrisk_codes → risk.riskid;\npolicy_codes → policy.code;\nprocedure_codes → procedures.code.\n","properties":{"evidence_codes":{"type":"array","description":"Evidence task definition codes (task_def.code); resolved to task_def.id for EVIDENCE mappings","items":{"type":"string"}},"action_item_codes":{"type":"array","description":"Action item (task_def) codes","items":{"type":"string"}},"policy_codes":{"type":"array","description":"Policy business codes (policy.code)","items":{"type":"string"}},"procedure_codes":{"type":"array","description":"Procedure business codes (procedures.code)","items":{"type":"string"}}}},"AssessmentQuestionsQueryRequest":{"type":"object","description":"Query request for assessment questions with filters or rules, fields, pagination, cursor, and sort","properties":{"filter":{"type":"object","additionalProperties":{"type":"string"}},"fields":{"type":"string"},"page_size":{"type":"integer","format":"int32","maximum":200,"minimum":1},"cursor":{"type":"string","pattern":"^[A-Za-z0-9+/=]*$"},"sort":{"type":"string","description":"Sort field with optional `+` (ascending) or `-` (descending) prefix. Use `code` to sort by the question code returned in responses (maps to `external_id` in the view). Examples: `+question_id`, `-programid`, `+code`, `external_id`."},"rules":{"type":"array","description":"Optional rules array. Allowed fields only: `frameworks.name`, `group_name`, `answer`. When non-empty, `filter` is ignored.","items":{"$ref":"#/components/schemas/CriteriaRule"}}}},"CriteriaRule":{"type":"object","properties":{"field":{"type":"string"},"operator":{"type":"string"},"value":{"type":"string"},"values":{"type":"array","items":{"type":"string"}}}},"CursorPaginationResponse":{"type":"object","properties":{"total_count":{"type":"integer","format":"int64"},"next_cursor":{"type":"string"},"data":{"type":"array","items":{"type":"object"}}}},"DocumentMeta":{"type":"object","properties":{"file_name":{"type":"string","description":"Original name of the file to be uploaded","example":"policy_document.pdf"},"document_id":{"type":"integer","format":"int32","description":"Unique identifier for the document","example":101},"signed_url":{"type":"string","description":"Pre-signed URL used to securely upload the document to storage (e.g., AWS S3)","example":"https://s3.amazonaws.com/bucket-name/upload-url"},"expires_in_seconds":{"type":"integer","format":"int32","description":"Time in seconds after which the signed URL will expire","example":300}},"required":["document_id","file_name"]},"DocumentUploadResponse":{"type":"object","properties":{"id":{"type":"string","description":"Unique reference ID for the upload request (e.g., evidenceId, policyId, actionItemId)","example":12345},"code":{"type":"string","description":"Human-readable reference code","example":"DOC-2026-001"},"documents":{"type":"array","description":"List of documents with upload details","items":{"$ref":"#/components/schemas/DocumentMeta"}}}},"ActionItemQueryRequest":{"type":"object","properties":{"filter":{"type":"object","additionalProperties":{"type":"string"}},"fields":{"type":"string"},"page_size":{"type":"integer","format":"int32","maximum":200,"minimum":1},"cursor":{"type":"string","pattern":"^[A-Za-z0-9+/=]*$"},"sort":{"type":"string","pattern":"^[+-]?(id|code|title|status)$"}}},"ActionItemResponse":{"type":"object","description":"Detailed response containing action item metadata, owners and timestamps.","properties":{"id":{"type":"integer","format":"int32","description":"Unique identifier of the action item","example":24337},"code":{"type":"string","description":"Unique action item code generated by the system","example":"AI-1"},"weakness_name":{"type":"string","description":"Title or short name of the action item","example":"SOC 2 Access Review Evidence"},"weakness_description":{"type":"string","description":"Detailed description providing additional context for the action item","example":"Quarterly SOC 2 evidence related to access reviews and user provisioning."},"status":{"type":"string","description":"Current status of the action item.","enum":["Not Started","In Progress","Review","Completed","Not Applicable"],"example":"In Progress"},"created_by":{"$ref":"#/components/schemas/UserMetadata","description":"User who created this action item"},"responsible_person":{"$ref":"#/components/schemas/UserMetadata","description":"User assigned to complete this action item","example":"Jane Smith"},"updated_at":{"type":"string","format":"date-time","description":"Timestamp when this action item was last updated","example":"2025-12-02T14:22:10"},"created_at":{"type":"string","format":"date-time","description":"Timestamp when this action item was created","example":"2025-12-01T09:05:00"},"type":{"type":"string","description":"Type of the action item"},"milestones":{"type":"string","description":"Milestones associated with this action item","example":"Q1 Security Audit"},"responsible_department":{"type":"string","description":"Responsible  department for this action item","example":"John Doe"},"corrective_action":{"type":"string","description":"Detailed corrective action plan to address the weakness","example":"Implement automated access review system"},"priority":{"type":"string","description":"Priority of the weakness","enum":["Low","Medium","High","Critical"],"example":"High"},"planned_start_date":{"type":"string","description":"Planned start date for this action item","example":"2025-12-15"},"actual_start_date":{"type":"string","description":"Actual start date when this action item was started","example":"2025-12-14"},"planned_completion_date":{"type":"string","description":"Target completion date for this action item","example":"2025-12-15"},"actual_completion_date":{"type":"string","description":"Actual date when this action item was completed","example":"2025-12-14"},"changes_to_milestones":{"type":"string","description":"Description of any changes made to the milestone","example":"Extended deadline due to resource constraints"},"source_of_weakness":{"type":"string","description":"Origin or source where this weakness was identified","example":"SOC 2 Audit Finding"},"requirements":{"type":"array","description":"List of compliance requirements or controls related to this action item","example":["SOC 2 CC6.1","ISO 27001 A.9.2.1"],"items":{"type":"string"}},"currency":{"type":"string","description":"Currency code for financial estimates","example":"USD"},"roadmap":{"type":"string","description":"Roadmap or project plan associated with this action item","example":3},"cost":{"type":"number","format":"float","description":"Estimated cost of this action item","example":10000},"effort_in_hours":{"type":"number","format":"float","description":"Estimated effort in hours required to complete this action item","example":12.5},"documents":{"type":"array","description":"List of uploaded documents with pre-signed URLs","items":{"$ref":"#/components/schemas/PresignedUrlResponse"}}},"required":["code","created_at","created_by","id","status","type","weakness_name"]},"CreateActionItemRequest":{"type":"object","description":"Request payload for creating a new action item","properties":{"weakness_name":{"type":"string","description":"Title or name of the action item. Should be concise and descriptive.","example":"Implement security patch","minLength":1},"weakness_description":{"type":"string","description":"Detailed description providing more context about the action item.","example":"Update all production servers with the latest security patches to address CVE-2023-1234"},"status":{"type":"string","default":"Not Started","description":"Status of the action item.","enum":["Not Started","In Progress","Review","Completed","Not Applicable"],"example":"Not Started","pattern":"^(Not Started|In Progress|Review|Completed|Not Applicable)$"},"corrective_action":{"type":"string","description":"Specific corrective actions or steps that need to be taken to resolve the issue.","example":"Install security updates"},"responsible_person":{"type":"string","description":"Email of the person responsible for completing this action item.","example":"john.doe@example.com"},"responsible_department":{"type":"string","description":"Department or team responsible for the action item.","example":"IT Security"},"efforts_in_hours":{"type":"integer","format":"int32","description":"Estimated effort required to complete the action item, in hours.","example":8,"maximum":8,"minimum":0},"roadmap":{"type":"string","description":"Roadmap or implementation plan outlining the steps to complete the action item.","enum":["3 months","6 months","12 months"],"example":3,"pattern":"^(3 months|6 months|12 months)$"},"priority":{"type":"string","default":"High","description":"Priority level indicating the importance and urgency of the action item.","enum":["High","Medium","Low","Critical"],"example":"High","pattern":"^(High|Medium|Low|Critical)$"},"planned_start_date":{"type":"string","description":"The date when work on the action item is scheduled to begin.","example":"2026-03-20"},"planned_end_date":{"type":"string","description":"The planned date by which the action item should be completed.","example":"2026-04-20"},"actual_start_date":{"type":"string","description":"The actual date  when work on the action item was started.","example":"2026-03-25"},"actual_end_date":{"type":"string","description":"The actual date  when the action item was completed.","example":"2026-04-30"},"currency":{"type":"string","default":"USD","description":"ISO currency code for cost estimation.","example":"USD","pattern":"^(USD|EUR|AUD|CAD|SEK|NZD|SGD|INR)$"},"cost":{"type":"integer","format":"int32","description":"Estimated or actual cost associated with the action item.","example":50},"milestones":{"type":"string","description":"Key milestones or checkpoints for tracking progress of the action item.","example":"Milestone 1: Planning complete\nMilestone 2: Implementation complete\nMilestone 3: Testing complete"},"change_in_milestone":{"type":"string","description":"Description of any changes made to the original milestones or plan.","example":"Extended testing phase by 1 week due to additional security requirements"}},"required":["currency","priority","weakness_name"]},"EvidencePartialUpdate":{"type":"object","description":"Payload to update engagement evidence","properties":{"title":{"type":"string","description":"Title of the evidence to update","example":"SOC 2 Access Review Evidence (Revised)"},"description":{"type":"string","description":"Description of the evidence to update","example":"Updated description after reviewer requested additional clarification."},"owner":{"type":"string","description":"User to set as the evidence owner","example":"john.doe@example.com"},"schedule":{"$ref":"#/components/schemas/EvidenceSchedule","description":"Recurring evidence schedule"}}},"EvidenceRequestPartialUpdate":{"type":"object","description":"Payload for partially updating evidence request details. Only fields provided will be updated.","properties":{"assigned_to":{"type":"string","description":"User ID or identifier the evidence request should be assigned to.","example":"joel@example.com"},"status":{"type":"string","description":"Updated status of the evidence request. If not provided, status remains unchanged.","enum":["Not Started","In Progress","Review","Completed","Not Applicable"],"example":"In Progress","pattern":"Not Started|In Progress|Review|Completed|Not Applicable"},"due_date":{"type":"string","format":"date-time","description":"New due date for the evidence request. If null or omitted, due date remains unchanged.","example":"2025-12-16"},"notes":{"type":"string","description":"Additional notes or comments regarding the evidence.","example":"Reviewed by admin. Waiting for supporting documents."}}},"AssessmentQuestionResponseUpdateRequest":{"type":"object","description":"Update an existing response (snake_case JSON: `id`, `response`, `provided_by`).","properties":{"id":{"type":"integer","format":"int32","description":"Primary key of the note row (`assessment_question_response.id`)","example":88},"response":{"type":"string","description":"Updated note body text","example":"Updated rationale.","minLength":1},"provided_by":{"type":"string","description":"Updated display name for who provided the response; defaults to the authenticated user's name when omitted"}},"required":["id","response"]},"ActionItemRequestPartialUpdate":{"type":"object","description":"Payload for partially updating action item details. Only fields provided will be updated.","properties":{"roadmap":{"type":"string","description":"Roadmap or implementation plan outlining the steps to complete the action item.","enum":["3 months","6 months","12 months"],"example":3,"pattern":"^(3 months|6 months|12 months)$"},"weakness_name":{"type":"string","description":"Title or name of the action item. If provided, must not be empty.","example":"Implement security patch"},"weakness_description":{"type":"string","description":"Detailed description providing more context about the action item.","example":"Update all production servers with the latest security patches to address CVE-2023-1234"},"responsible_person":{"type":"string","description":"Email of the person responsible for completing this action item.","example":"john.doe@example.com"},"status":{"type":"string","description":"Updated status of the action item. If not provided, status remains unchanged.","enum":["Not Started","In Progress","Review","Completed","Not Applicable"],"example":"In Progress","pattern":"^(Not Started|In Progress|Review|Completed|Not Applicable)$"},"corrective_action":{"type":"string","description":"Specific corrective actions or steps that need to be taken to resolve the issue.","example":"Install security updates"},"responsible_department":{"type":"string","description":"Department or team responsible for the action item.","example":"IT Security"},"efforts_in_hours":{"type":"integer","format":"int32","description":"Estimated effort required to complete the action item, in hours.","example":8,"maximum":8,"minimum":0},"priority":{"type":"string","default":"High","description":"Priority level indicating the importance and urgency of the action item.","enum":["High","Medium","Low","Critical"],"example":"High","pattern":"^(High|Medium|Low|Critical)$"},"planned_start_date":{"type":"string","description":"The date when work on the action item is scheduled to begin.","example":"2026-03-20"},"planned_end_date":{"type":"string","description":"The planned date by which the action item should be completed.","example":"2026-04-20"},"actual_start_date":{"type":"string","description":"The actual date when work on the action item was started.","example":"2026-03-25"},"actual_end_date":{"type":"string","description":"The actual date when the action item was completed.","example":"2026-04-30"},"currency":{"type":"string","default":"USD","description":"ISO currency code for cost estimation.","example":"USD","pattern":"^(USD|EUR|AUD|CAD|SEK|NZD|SGD|INR)$"},"cost":{"type":"integer","format":"int32","description":"Estimated or actual cost associated with the action item.","example":50},"milestones":{"type":"string","description":"Key milestones or checkpoints for tracking progress of the action item.","example":"Milestone 1: Planning complete\nMilestone 2: Implementation complete\nMilestone 3: Testing complete"},"change_in_milestone":{"type":"string","description":"Description of any changes made to the original milestones or plan.","example":"Extended testing phase by 1 week due to additional security requirements"},"notes":{"type":"string","description":"Additional notes or comments regarding the action item.","example":"Reviewed by admin. Waiting for supporting documents."}}},"ActionPatchResponse":{"type":"object","description":"Response returned after partially updating an action item","properties":{"id":{"type":"integer","format":"int32","description":"Unique identifier of the action item","example":75},"weakness_name":{"type":"string","description":"Title of the action item","example":"Implement security patch"},"weakness_description":{"type":"string","description":"Description of the action item","example":"Update all production servers with the latest security patches"},"responsible_person":{"type":"string","description":"Responsible person for this action item","example":"john.doe@example.com"},"updated_status":{"type":"string","description":"Updated status of the action item","enum":["Not Started","In Progress","Review","Completed","Not Applicable"],"example":"In Progress"},"priority":{"type":"string","description":"Priority level indicating the importance and urgency of the action item","enum":["High","Medium","Low","Critical"],"example":"High"},"corrective_action":{"type":"string","description":"Specific corrective actions or steps that need to be taken to resolve the issue","example":"Install security updates"},"responsible_department":{"type":"string","description":"Department or team responsible for the action item","example":"IT Security"},"efforts_in_hours":{"type":"number","format":"float","description":"Estimated effort required to complete the action item, in hours","example":8},"roadmap":{"type":"string","description":"Roadmap or implementation plan outlining the steps to complete the action item","example":3},"planned_start_date":{"type":"string","description":"Planned start date (yyyy-MM-dd format)","example":"2026-03-20"},"planned_end_date":{"type":"string","description":"Planned end date (yyyy-MM-dd format)","example":"2026-04-20"},"actual_start_date":{"type":"string","description":"Actual start date (yyyy-MM-dd format)","example":"2026-03-25"},"actual_end_date":{"type":"string","description":"Actual end date (yyyy-MM-dd format)","example":"2026-04-30"},"currency":{"type":"string","description":"ISO currency code for cost estimation","example":"USD"},"cost":{"type":"number","format":"float","description":"Estimated or actual cost associated with the action item","example":50},"milestones":{"type":"string","description":"Key milestones or checkpoints for tracking progress of the action item"},"change_in_milestone":{"type":"string","description":"Description of any changes made to the original milestones or plan"},"updated_notes":{"type":"string","description":"Updated notes of the action item","example":"Updated notes"}}},"ClientRiskPaginatedResponse":{"type":"object","description":"API response containing client details and paginated list of risks","properties":{"client":{"$ref":"#/components/schemas/Client","description":"Client metadata"},"risk_summary":{"$ref":"#/components/schemas/RiskScore","description":"Overall summary of risk analysis for the client"},"risks":{"$ref":"#/components/schemas/RiskPaginatedResponse","description":"Paginated list of risks for this client"}}},"RiskPaginatedResponse":{"type":"object","description":"Paginated response for risk list","properties":{"total_count":{"type":"integer","format":"int64","description":"Total number of risks for the client"},"next_cursor":{"type":"string","description":"Cursor for fetching next set of items"},"data":{"type":"array","description":"List of risks for this page","items":{"$ref":"#/components/schemas/RiskResponse"}}}},"RiskScore":{"type":"object","description":"Risk assessment information including overall score and breakdown","properties":{"overall_score":{"type":"integer","format":"int32","description":"Overall risk score (0-100 scale, where higher is better/lower risk)"},"risk_level":{"type":"string","description":"Overall risk level assessment (e.g., 'Low', 'Medium', 'High', 'Critical')"},"updated_at":{"type":"string","format":"date-time","description":"ISO 8601 timestamp when the risk assessment was last performed"},"risk_breakdown":{"type":"object","additionalProperties":{"type":"integer","format":"int32"}}}},"ReportDocumentResponse":{"type":"object","description":"Represents a downloadable report document, including its metadata and a time-limited signed URL.","properties":{"id":{"type":"integer","format":"int32","description":"Unique identifier of the report document.","example":1234},"name":{"type":"string","description":"Name or title of the report.","example":"Compliance Health Report"},"signed_url":{"type":"string","description":"Pre-signed, time-limited URL used to securely download the report document.","example":"https://bucket.s3.amazonaws.com/report.pdf?X-Amz-SignedHeaders=..."},"expires_in_seconds":{"type":"integer","format":"int64","description":"Number of seconds until the signed URL expires. After this time, the URL becomes invalid.","example":3600}}},"ActionItemsProgress":{"type":"object","description":"Progress tracking information for ActionItems","properties":{"completed":{"type":"integer","format":"int32","description":"The status is marked as 'Completed'"},"review":{"type":"integer","format":"int32","description":"The status is marked as 'Review'"},"in_progress":{"type":"integer","format":"int32","description":"The status is marked as 'In Progress'"},"not_started":{"type":"integer","format":"int32","description":"The status is marked as 'Not Started'"},"not_applicable":{"type":"integer","format":"int32","description":"The status is marked as 'Not Applicable'"},"total":{"type":"integer","format":"int32","description":"Total ActionItems"},"completion_percentage":{"type":"number","format":"float","description":"ActionItems Completion Percentage"}}},"AssessmentBreakdown":{"type":"object","description":"Breakdown of responses","properties":{"yes":{"type":"integer","format":"int32","description":"The number/count of responses marked as 'Yes'"},"no":{"type":"integer","format":"int32","description":"The number/count of responses marked as 'No'"},"partially":{"type":"integer","format":"int32","description":"The number/count of responses marked as 'Partially'"},"not_answered":{"type":"integer","format":"int32","description":"The number/count of responses marked as 'Not Answered'"},"not_applicable":{"type":"integer","format":"int32","description":"The number/count of responses marked as 'Not Applicable'"},"answering_percentage":{"type":"number","format":"float","description":"Percentage of assessment questions answered"},"total":{"type":"integer","format":"int32","description":"Total number of questions"}}},"AssessmentsProgress":{"type":"object","description":"Progress tracking information for Assessments","properties":{"yes":{"type":"integer","format":"int32","description":"The number/count of responses marked as 'Yes'"},"no":{"type":"integer","format":"int32","description":"The number/count of responses marked as 'No'"},"partially":{"type":"integer","format":"int32","description":"The number/count of responses marked as 'Partially'"},"not_answered":{"type":"integer","format":"int32","description":"The number/count of responses marked as 'Not Answered'"},"not_applicable":{"type":"integer","format":"int32","description":"The number/count of responses marked as 'Not Applicable'"},"answering_percentage":{"type":"number","format":"float","description":"Assessment Answering Percentage"},"total":{"type":"integer","format":"int32","description":"Total questions"}}},"ComplianceBreakdown":{"type":"object","description":"Breakdown of compliance","properties":{"compliant":{"type":"integer","format":"int32","description":"The number/count of responses marked as 'Compliant'"},"in_review":{"type":"integer","format":"int32","description":"The number/count of responses marked as 'In Review'"},"not_applicable":{"type":"integer","format":"int32","description":"The number/count of responses marked as 'Not Applicable'"},"not_assessed":{"type":"integer","format":"int32","description":"The number/count of responses marked as 'Not Assessed'"},"not_compliant":{"type":"integer","format":"int32","description":"The number/count of responses marked as 'Not Compliant'"},"partially_compliant":{"type":"integer","format":"int32","description":"The number/count of responses marked as 'Partially Compliant'"},"compliance_achieved_percentage":{"type":"number","format":"float","description":"Percentage of overall compliance achieved"},"total":{"type":"integer","format":"int32","description":"Total objectives"},"updated_at":{"type":"string","format":"date-time","description":"ISO 8601 timestamp when the compliance score was last calculated","example":"2025-09-15T17:00:00Z"}}},"ComplianceScore":{"type":"object","description":"Compliance score information with trend data","properties":{"overall_score":{"type":"number","format":"float","description":"Overall compliance score (0-10 scale)","example":7.8},"score_label":{"type":"string","description":"Human-readable label for the score (e.g., 'Excellent', 'Good', 'Average', 'Poor')"},"updated_at":{"type":"string","format":"date-time","description":"ISO 8601 timestamp when the compliance score was last calculated","example":"2025-09-15T17:00:00Z"},"trend":{"$ref":"#/components/schemas/Trend"}}},"ControlsProgress":{"type":"object","description":"Progress tracking information for Controls","properties":{"implemented":{"type":"integer","format":"int32","description":"The number/count of controls that are 'Implemented'"},"partially_implemented":{"type":"integer","format":"int32","description":"The number/count of controls that are 'Partially Implemented'"},"not_implemented":{"type":"integer","format":"int32","description":"The number/count of controls that are 'Not Implemented'"},"in_progress":{"type":"integer","format":"int32","description":"The number/count of controls that are 'In Progress'"},"alternative_implementation":{"type":"integer","format":"int32","description":"The number/count of controls that are 'Alternative Implementation'"},"not_applicable":{"type":"integer","format":"int32","description":"The number/count of controls that are 'Not Applicable'"},"implementation_percentage":{"type":"number","format":"float","description":"The percentage of controls that are Implemented"},"total":{"type":"integer","format":"int32","description":"Total controls"}}},"DocumentsProgress":{"type":"object","description":"Progress tracking information for Documents","properties":{"approved":{"type":"integer","format":"int32","description":"Number of documents in 'Approved' status.","example":5},"in_review":{"type":"integer","format":"int32","description":"Number of documents in 'In Review' status.","example":2},"ready_for_approval":{"type":"integer","format":"int32","description":"Number of documents in 'Ready For Approval' status.","example":1},"in_progress":{"type":"integer","format":"int32","description":"Number of documents in 'In Progress' status.","example":3},"draft":{"type":"integer","format":"int32","description":"Number of documents in 'Draft' status.","example":3},"approved_percentage":{"type":"number","format":"float","description":"Percentage of documents that are approved (0–100).","example":62.5},"total":{"type":"integer","format":"int32","description":"Total number of policy documents for this client.","example":8}}},"Health":{"type":"object","description":"Health data for a single client/tenant","properties":{"client":{"$ref":"#/components/schemas/Client"},"compliance_score":{"$ref":"#/components/schemas/ComplianceScore"},"risk_score":{"$ref":"#/components/schemas/RiskScore"},"frameworks":{"type":"array","description":"Framework-specific compliance scores and overall framework performance","items":{"$ref":"#/components/schemas/Framework"}},"work_progress":{"$ref":"#/components/schemas/WorkProgress"},"updated_at":{"type":"string","format":"date-time","description":"ISO 8601 timestamp when this client's health data was last updated","example":"2025-09-15T17:00:00Z"}}},"Trend":{"type":"object","description":"Trend information showing score changes over different time periods","properties":{"last_30_days":{"type":"integer","format":"int32","description":"Score change over the last 30 days (positive = improvement, negative = decline)"},"last_60_days":{"type":"integer","format":"int32","description":"Score change over the last 60 days (positive = improvement, negative = decline)"},"last_90_days":{"type":"integer","format":"int32","description":"Score change over the last 90 days (positive = improvement, negative = decline)"}}},"WorkProgress":{"type":"object","description":"Comprehensive work progress tracking across different work categories","properties":{"evidence":{"$ref":"#/components/schemas/EvidenceProgress"},"controls":{"$ref":"#/components/schemas/ControlsProgress"},"action_items":{"$ref":"#/components/schemas/ActionItemsProgress"},"assessments":{"$ref":"#/components/schemas/AssessmentsProgress"},"documents":{"$ref":"#/components/schemas/DocumentsProgress"},"overall_progress_score":{"type":"integer","format":"int32","description":"Aggregated progress score across all work categories (0-100 scale)","example":85},"updated_at":{"type":"string","format":"date-time","description":"ISO 8601 timestamp when work progress was last calculated","example":"2025-09-15T17:00:00Z"}}},"ComplianceHealth":{"type":"object","description":"Compliance health response containing compliance health metrics for clients of an MSP with pagination.","properties":{"data":{"type":"array","description":"Array of health data for each client","items":{"$ref":"#/components/schemas/Health"}},"total_count":{"type":"integer","format":"int32","description":"Total number of clients available (across all pages)","example":150},"next_cursor":{"type":"string","description":"Opaque cursor for fetching the next page of results (Base64 encoded)","example":"eyJjbGllbnRfaWQiOiJ0ZW5hbnQ0NTYifQ=="}}},"AssessmentQuestion":{"type":"object","description":"Assessment question details","properties":{"id":{"type":"integer","format":"int32","description":"Assessment question identifier"},"code":{"type":"string","description":"Assessment question code"},"title":{"type":"string","description":"Assessment question title"},"answer":{"type":"string","description":"Assessment question answer"}}},"AuditEvidenceRequest":{"type":"object","description":"Evidence Request details","properties":{"id":{"type":"integer","format":"int32","description":"Evidence Request identifier"},"code":{"type":"string","description":"Evidence Request code"},"title":{"type":"string","description":"Evidence Request title"},"audit_result":{"type":"string","description":"Audit result"},"detailed_evaluation":{"$ref":"#/components/schemas/DetailedEvaluation","description":"Audit result detailed evaluation"}}},"AuditTest":{"type":"object","description":"Audit test details","properties":{"audit_name":{"type":"string","description":"Audit test name"},"evidence_requests":{"type":"array","description":"List of audit evidence requests","items":{"$ref":"#/components/schemas/AuditEvidenceRequest"}}}},"DetailedEvaluation":{"type":"object","description":"Audit test details","properties":{"design_and_implementation":{"type":"string","description":"Design and implementation"},"operational_status":{"type":"string","description":"Operational status"},"quality_of_evidence":{"type":"string","description":"Quality of evidence"},"findings":{"type":"string","description":"Evidence Request findings"}}},"Maturity":{"type":"object","description":"Maturity level details","properties":{"id":{"type":"integer","format":"int32","description":"Maturity identifier","example":40183},"name":{"type":"string","description":"Maturity level name","example":"Optimizing"},"description":{"type":"string","description":"Maturity level description"},"score":{"type":"integer","format":"int32","description":"Maturity score","example":4}}},"ObjectiveDetail":{"type":"object","description":"Objective (requirement) item with scope and lifecycle metadata","properties":{"id":{"type":"integer","format":"int32","description":"Requirement / objective identifier","example":393},"code":{"type":"string","description":"Display requirement code","example":4.1},"name":{"type":"string","description":"Objective title","example":"Understanding the organization and its context"},"description":{"type":"string","description":"Objective description"},"status":{"type":"string","description":"Compliance status label","example":"Compliant"},"level1_code":{"type":"string","description":"Level 1 grouping code"},"level1_name":{"type":"string","description":"Level 1 grouping name"},"level2_code":{"type":"string","description":"Level 2 grouping code"},"level2_name":{"type":"string","description":"Level 2 grouping name"},"created_at":{"type":"string","format":"date-time","description":"Timestamp when this objective was created","example":"2025-12-01T09:05:00"},"updated_at":{"type":"string","format":"date-time","description":"Timestamp when this objective was last updated","example":"2025-12-01T09:05:00"},"in_scope":{"type":"boolean","description":"Whether the objective is in scope for the assessment"},"type":{"type":"string","description":"Scope identifier","example":"clauses"},"implementation_details":{"type":"string","description":"Implementation Details","example":"clauses"},"automated_test":{"type":"string","description":"Automated Test"},"automated_tested_on":{"type":"string","format":"date-time","description":"Automated Test On"},"current_maturity":{"$ref":"#/components/schemas/Maturity","description":"Current Maturity level information"},"target_maturity":{"$ref":"#/components/schemas/Maturity","description":"Target Maturity level information"},"assessment_questions":{"type":"array","description":"Assessment question information","items":{"$ref":"#/components/schemas/AssessmentQuestion"}},"audit_tests":{"type":"array","description":"Audit tests information","items":{"$ref":"#/components/schemas/AuditTest"}},"controls":{"type":"array","description":"List of associated controls","items":{"$ref":"#/components/schemas/Entity"}},"documents":{"type":"array","description":"List of associated documents","items":{"$ref":"#/components/schemas/Entity"}},"evidences":{"type":"array","description":"List of associated evidences","items":{"$ref":"#/components/schemas/Entity"}},"action_items":{"type":"array","description":"List of associated action items","items":{"$ref":"#/components/schemas/Entity"}},"risks":{"type":"array","description":"List of associated risks","items":{"$ref":"#/components/schemas/Entity"}},"responsible_party":{"type":"array","description":"Responsible parties information","items":{"$ref":"#/components/schemas/ResponsibleParty"}},"cross_walks":{"type":"array","description":"Cross walks","items":{"$ref":"#/components/schemas/Objective"}}},"required":["created_at","updated_at"]},"ResponsibleParty":{"type":"object","description":"Responsible party details","properties":{"id":{"type":"integer","format":"int32","description":"Responsible party identifier"},"name":{"type":"string"},"responsibility":{"type":"string"},"party_name":{"type":"string","description":"Party name"}}},"ClientObjectiveSummaryResponse":{"type":"object","description":"Objective summary for a single partner client","properties":{"client":{"$ref":"#/components/schemas/Client","description":"Client metadata"},"framework_stats":{"type":"array","description":"Aggregated objective summary by framework for the client","items":{"$ref":"#/components/schemas/FrameworkStats"}}}},"FrameworkStats":{"type":"object","description":"Objective summary stats for a single framework","properties":{"id":{"type":"integer","format":"int32","description":"Framework id","example":3},"name":{"type":"string","description":"Framework name","example":"ISO-27001"},"objective_summary":{"$ref":"#/components/schemas/ObjectiveSummary","description":"Objective completion metrics"}}},"DocumentResponse":{"type":"object","properties":{"document_id":{"type":"integer","format":"int32"},"file_name":{"type":"string"},"signed_url":{"type":"string"},"expires_at":{"type":"string","format":"date-time"}}},"AssessmentQuestionGroupSummaryDTO":{"type":"object","description":"Answer counts for a single assessment question group","properties":{"no":{"type":"integer","format":"int32","description":"Count of 'No' answers","example":0},"na":{"type":"integer","format":"int32","description":"Count of 'N/A' answers","example":0},"answered":{"type":"integer","format":"int32","description":"Count of questions that have any answer recorded","example":8},"yes":{"type":"integer","format":"int32","description":"Count of 'Yes' answers","example":8},"name":{"type":"string","description":"Display name of the question group","example":"Human Resources Security"},"count":{"type":"integer","format":"int32","description":"Total questions in this group","example":16},"not_answered":{"type":"integer","format":"int32","description":"Questions without an answer","example":8},"partially":{"type":"integer","format":"int32","description":"Count of 'Partially' answers","example":0}}},"AssessmentStatsDTO":{"type":"object","description":"Overall assessment statistics and answer distribution","properties":{"total_questions":{"type":"integer","format":"int32","description":"Total number of questions","example":263},"no":{"type":"integer","format":"int32","description":"Count of 'No' answers","example":11},"answered_questions":{"type":"integer","format":"int32","description":"Questions with an answer recorded","example":82},"na":{"type":"integer","format":"int32","description":"Count of 'N/A' answers","example":5},"yes":{"type":"integer","format":"int32","description":"Count of 'Yes' answers","example":58},"partially":{"type":"integer","format":"int32","description":"Count of 'Partially' answers","example":8},"answered_questions_percentage":{"type":"integer","format":"int32","description":"Percentage of questions answered","example":31}}},"AssessmentSummaryDTO":{"type":"object","description":"Aggregated assessment summary: question groups, grades, and overall stats; per-framework fields are present only when the client requests framework-level data (e.g. `include_framework_assessment_stats=true` on GET .../assessments/summary).","properties":{"assessment_score_percentage":{"type":"integer","format":"int32","description":"Assessment Score Percentage based on common assessment question"},"question_group_progress":{"type":"array","description":"Assessment progress by question group. ","items":{"$ref":"#/components/schemas/AssessmentQuestionGroupSummaryDTO"}},"frameworks_count":{"type":"integer","format":"int32","description":"Number of imported frameworks.","example":3},"frameworks":{"type":"array","description":"Per-framework statistics and assessment score percentage. Present only when framework details are requested; otherwise null.","items":{"$ref":"#/components/schemas/FrameworkAssessmentSummaryDTO"}},"answering_progress":{"$ref":"#/components/schemas/AssessmentStatsDTO","description":"Overall totals and answer distribution. "}}},"FrameworkAssessmentSummaryDTO":{"type":"object","description":"Assessment stats and grade for one imported framework","properties":{"framework_id":{"type":"integer","format":"int32","description":"Framework program id","example":3},"framework_name":{"type":"string","description":"Framework display name","example":"ISO-27001"},"assessment_stats":{"$ref":"#/components/schemas/AssessmentStatsDTO","description":"Answer distribution for this framework only"},"assessment_score_percentage":{"type":"integer","format":"int32","description":"Assessment Score Percentage based on common assessment question"}}},"ActionItem":{"type":"object","description":"action item","properties":{"id":{"type":"integer","format":"int32"},"title":{"type":"string"},"code":{"type":"string"},"description":{"type":"string"},"due_at":{"type":"string","description":"Due date (yyyy-MM-dd)","example":"2025-09-15"}}},"AnswerOption":{"type":"object","description":"Answer option","properties":{"id":{"type":"integer","format":"int32"},"answer":{"type":"string"},"order":{"type":"integer","format":"int32"}}},"AssessmentQuestionResponse":{"type":"object","description":"assessment question response","properties":{"id":{"type":"integer","format":"int32"},"code":{"type":"string"},"owner":{"$ref":"#/components/schemas/Owner"},"question":{"type":"string"},"status":{"type":"string"},"auditor_status":{"type":"string"},"answer_options":{"type":"array","items":{"$ref":"#/components/schemas/AnswerOption"}},"action_items":{"type":"array","items":{"$ref":"#/components/schemas/ActionItem"}},"objectives":{"type":"array","items":{"$ref":"#/components/schemas/Objective"}},"updated_at":{"type":"string","description":"Last update date (yyyy-MM-dd)","example":"2025-09-15"},"answer":{"type":"string"},"answered_at":{"type":"string","description":"Date when the answer was submitted (yyyy-MM-dd)","example":"2025-09-15"},"responses":{"type":"array","items":{"$ref":"#/components/schemas/QuestionNote"}},"answer_id":{"type":"integer","format":"int32"},"option_id":{"type":"integer","format":"int32"},"group_name":{"type":"string"},"illustrative_example":{"type":"string"},"policies":{"type":"array","items":{"$ref":"#/components/schemas/Policy"}},"procedures":{"type":"array","items":{"$ref":"#/components/schemas/Procedure"}},"evidences":{"type":"array","items":{"$ref":"#/components/schemas/Evidence"}},"past_answer":{"type":"string"}}},"Evidence":{"type":"object","description":"evidence","properties":{"id":{"type":"integer","format":"int32"},"title":{"type":"string"},"evidence_code":{"type":"string"}}},"Policy":{"type":"object","description":"policy","properties":{"id":{"type":"integer","format":"int32"},"policy_code":{"type":"string"},"name":{"type":"string"}}},"Procedure":{"type":"object","description":"procedure","properties":{"id":{"type":"integer","format":"int32"},"name":{"type":"string"},"procedure_code":{"type":"string"}}},"QuestionNote":{"type":"object","description":"Question Response","properties":{"id":{"type":"integer","format":"int32"},"response":{"type":"string"},"created_at":{"type":"string","description":"Created date (yyyy-MM-dd)","example":"2025-09-15"},"updated_at":{"type":"string","description":"Updated date (yyyy-MM-dd)","example":"2025-09-15"},"created_by":{"$ref":"#/components/schemas/Owner"}}},"AssessmentSummary":{"type":"object","description":"Overall assessment completion metrics for a client tenant","properties":{"yes":{"type":"integer","format":"int32","description":"The number/count of responses marked as 'Yes'"},"no":{"type":"integer","format":"int32","description":"The number/count of responses marked as 'No'"},"partially":{"type":"integer","format":"int32","description":"The number/count of responses marked as 'Partially'"},"not_answered":{"type":"integer","format":"int32","description":"The number/count of responses marked as 'Not Answered'"},"not_applicable":{"type":"integer","format":"int32","description":"The number/count of responses marked as 'Not Applicable'"},"answering_percentage":{"type":"number","format":"float","description":"Assessment Answering Percentage"},"total":{"type":"integer","format":"int32","description":"Total questions"}}},"ClientAssessmentSummaryResponse":{"type":"object","description":"Assessment summary for a single partner client","properties":{"client":{"$ref":"#/components/schemas/Client","description":"Client metadata"},"assessment_summary":{"$ref":"#/components/schemas/AssessmentSummary","description":"Aggregated assessment question completion for the client"}}}},"securitySchemes":{"apiKey":{"type":"apiKey","description":"The API key generated from ScalePad application.<br> Example: 'c4d67eca-3b32ed26-b2412e47-2f634617-7e91a0f4-5c8d2b67-e3a19f0b-46d7c582'<br>","name":"x-api-key","in":"header"}}}}