{"openapi":"3.1.0","info":{"title":"Vendorica Public API","version":"1.0.0","description":"Vendorica public API (v1). Authenticate with an API key issued from your organization settings using `Authorization: Bearer vnd_live_...`. Guides, authentication, pagination, rate limits and error codes: https://docs.vendorica.com."},"servers":[{"url":"https://api.vendorica.com/v1"}],"components":{"schemas":{"AuditLogEntry":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"entityType":{"type":"string"},"entityId":{"type":"string"},"operation":{"type":"string"},"oldValues":{"type":["object","null"],"additionalProperties":{}},"newValues":{"type":["object","null"],"additionalProperties":{}},"changedFields":{"type":["array","null"],"items":{"type":"string"}},"userId":{"type":["string","null"]},"userEmail":{"type":["string","null"]},"userRole":{"type":["string","null"]},"ipAddress":{"type":["string","null"]},"userAgent":{"type":["string","null"]},"requestId":{"type":["string","null"]},"description":{"type":["string","null"]},"severity":{"type":"string"},"createdAt":{"type":["string","null"],"format":"date-time"}},"required":["id","entityType","entityId","operation","oldValues","newValues","changedFields","userId","userEmail","userRole","ipAddress","userAgent","requestId","description","severity","createdAt"],"additionalProperties":{}},"CompliancePosture":{"type":"object","properties":{"overallScore":{"type":"number"},"byFramework":{"type":"array","items":{"$ref":"#/components/schemas/FrameworkScore"}}},"required":["overallScore","byFramework"]},"Contract":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"vendorId":{"type":"string","format":"uuid"},"title":{"type":"string"},"contractType":{"type":["string","null"]},"contractTypeId":{"type":["string","null"],"format":"uuid"},"startDate":{"type":["string","null"]},"endDate":{"type":["string","null"]},"value":{"type":["string","null"]},"currency":{"type":["string","null"]},"status":{"type":["string","null"]},"contractStatusId":{"type":["string","null"],"format":"uuid"},"riskNotes":{"type":["string","null"]},"arrangementReference":{"type":["string","null"]},"isIntragroup":{"type":"boolean"},"clientNoticePeriodDays":{"type":["integer","null"]},"vendorNoticePeriodDays":{"type":["integer","null"]},"terminationDate":{"type":["string","null"]},"signingDate":{"type":["string","null"]},"governingLaw":{"type":["string","null"]},"storesData":{"type":["boolean","null"]},"dataSensitivity":{"type":["string","null"],"enum":["low","medium","high","very_high",null]},"relianceLevel":{"type":["string","null"],"enum":["none","low","medium","high","critical",null]},"dataLocationAtRest":{"type":["array","null"],"items":{"type":"string"}},"dataProcessingLocation":{"type":["array","null"],"items":{"type":"string"}},"outsourcingClassification":{"type":["string","null"],"enum":["outsourcing","non_outsourcing",null]},"outsourcingClassificationRationale":{"type":["string","null"]},"involvesPersonalData":{"type":["boolean","null"]},"nextRenewalDate":{"type":["string","null"]},"cloudServiceModel":{"type":["string","null"],"enum":["iaas","paas","saas","other",null]},"cloudDeploymentModel":{"type":["string","null"],"enum":["public","private","hybrid","community",null]},"lastAuditDate":{"type":["string","null"]},"nextAuditDate":{"type":["string","null"]},"alternativeProvidersIdentified":{"type":["boolean","null"]},"alternativeProvidersNotes":{"type":["string","null"]},"ebaArrangementType":{"type":["string","null"],"enum":["eba_CO:x1","eba_CO:x2","eba_CO:x3",null]},"businessOwnerId":{"type":["string","null"],"format":"uuid"},"approvalStatus":{"type":"string"},"approvalInstanceId":{"type":["string","null"],"format":"uuid"},"businessUnitIds":{"type":"array","items":{"type":"string","format":"uuid"}},"createdAt":{"type":["string","null"],"format":"date-time"},"updatedAt":{"type":["string","null"],"format":"date-time"},"statusPhase":{"type":["string","null"],"enum":["draft","pending","in_force","ended","archived",null]},"vendor":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"name":{"type":"string"}},"required":["id","name"]},"businessOwner":{"type":["object","null"],"properties":{"id":{"type":"string","format":"uuid"},"firstName":{"type":["string","null"]},"lastName":{"type":["string","null"]},"email":{"type":"string"}},"required":["id","firstName","lastName","email"]}},"required":["id","vendorId","title","contractType","contractTypeId","startDate","endDate","value","currency","status","contractStatusId","riskNotes","arrangementReference","isIntragroup","clientNoticePeriodDays","vendorNoticePeriodDays","terminationDate","signingDate","governingLaw","storesData","dataSensitivity","relianceLevel","dataLocationAtRest","dataProcessingLocation","outsourcingClassification","outsourcingClassificationRationale","involvesPersonalData","nextRenewalDate","cloudServiceModel","cloudDeploymentModel","lastAuditDate","nextAuditDate","alternativeProvidersIdentified","alternativeProvidersNotes","ebaArrangementType","businessOwnerId","approvalStatus","approvalInstanceId","businessUnitIds","createdAt","updatedAt","statusPhase","vendor","businessOwner"]},"ContractDocument":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"contractId":{"type":"string","format":"uuid"},"docType":{"type":"string"},"fileId":{"type":["string","null"],"format":"uuid"},"filename":{"type":["string","null"]},"mimeType":{"type":["string","null"]},"sizeBytes":{"type":["integer","null"]},"scanStatus":{"type":["string","null"]},"addedByUserId":{"type":["string","null"],"format":"uuid"},"createdAt":{"type":["string","null"],"format":"date-time"},"supersededById":{"type":["string","null"],"format":"uuid"},"supersededAt":{"type":["string","null"],"format":"date-time"}},"required":["id","contractId","docType","fileId","filename","mimeType","sizeBytes","scanStatus","addedByUserId","createdAt","supersededById","supersededAt"]},"Control":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"organizationId":{"type":"string","format":"uuid"},"displayId":{"type":["string","null"]},"name":{"type":"string"},"description":{"type":["string","null"]},"status":{"type":["string","null"]},"domain":{"type":["string","null"]},"ownerUserId":{"type":["string","null"],"format":"uuid"},"effectiveDate":{"type":["string","null"]},"createdAt":{"type":["string","null"],"format":"date-time"},"updatedAt":{"type":["string","null"],"format":"date-time"}},"required":["id","organizationId","displayId","name","description","status","domain","ownerUserId","effectiveDate","createdAt","updatedAt"],"additionalProperties":{}},"ControlFrameworkMapping":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"controlId":{"type":"string","format":"uuid"},"frameworkId":{"type":"string","format":"uuid"},"frameworkCode":{"type":"string"},"frameworkName":{"type":"string"},"citationId":{"type":["string","null"],"format":"uuid"},"citationArticleRef":{"type":["string","null"]},"citationTitle":{"type":["string","null"]},"mappingSource":{"type":"string"},"confirmedAt":{"type":["string","null"],"format":"date-time"},"createdAt":{"type":"string","format":"date-time"}},"required":["id","controlId","frameworkId","frameworkCode","frameworkName","citationId","citationArticleRef","citationTitle","mappingSource","confirmedAt","createdAt"]},"CursorMeta":{"type":"object","properties":{"nextCursor":{"type":["string","null"]},"hasMore":{"type":"boolean"},"limit":{"type":"integer"}},"required":["nextCursor","hasMore","limit"]},"ErrorResponse":{"type":"object","properties":{"success":{"type":"boolean","enum":[false]},"error":{"type":"string"},"code":{"type":"string"},"details":{},"timestamp":{"type":"string","format":"date-time"},"requestId":{"type":"string"}},"required":["success","error","code","timestamp"]},"EvidenceItem":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"organizationId":{"type":"string","format":"uuid"},"controlId":{"type":"string","format":"uuid"},"controlDisplayId":{"type":["string","null"]},"controlName":{"type":["string","null"]},"testType":{"type":"string"},"source":{"type":"string"},"status":{"type":"string"},"summary":{"type":["string","null"]},"isSensitive":{"type":"boolean"},"collectedAt":{"type":"string","format":"date-time"},"expiresAt":{"type":["string","null"],"format":"date-time"},"supersededBy":{"type":["string","null"],"format":"uuid"}},"required":["id","organizationId","controlId","controlDisplayId","controlName","testType","source","status","summary","isSensitive","collectedAt","expiresAt","supersededBy"],"additionalProperties":{}},"EvidenceUpload":{"type":"object","properties":{"evidence":{"$ref":"#/components/schemas/EvidenceItem"},"file":{"$ref":"#/components/schemas/UploadedFile"}},"required":["evidence","file"]},"FrameworkBreakdown":{"type":"object","properties":{"overall":{"$ref":"#/components/schemas/FrameworkScore"},"byCategory":{"type":"array","items":{"type":"object","properties":{"category":{"type":"string"},"controlsTotal":{"type":"integer"},"controlsOk":{"type":"integer"},"readinessPct":{"type":["number","null"]}},"required":["category","controlsTotal","controlsOk","readinessPct"]}},"byCitation":{"type":"array","items":{"type":"object","properties":{"citationId":{"type":"string","format":"uuid"},"articleRef":{"type":"string"},"title":{"type":"string"},"mappedControls":{"type":"array","items":{"type":"object","properties":{"controlId":{"type":"string","format":"uuid"},"displayId":{"type":"string"},"name":{"type":"string"},"status":{"type":"string"}},"required":["controlId","displayId","name","status"]}}},"required":["citationId","articleRef","title","mappedControls"]}}},"required":["overall","byCategory","byCitation"]},"FrameworkScore":{"type":"object","properties":{"frameworkId":{"type":"string","format":"uuid"},"code":{"type":"string"},"name":{"type":"string"},"controlsTotal":{"type":"integer"},"controlsOk":{"type":"integer"},"controlsNeedsEvidence":{"type":"integer"},"controlsExpiringSoon":{"type":"integer"},"controlsExpired":{"type":"integer"},"controlsDeactivated":{"type":"integer"},"readinessPct":{"type":["number","null"]}},"required":["frameworkId","code","name","controlsTotal","controlsOk","controlsNeedsEvidence","controlsExpiringSoon","controlsExpired","controlsDeactivated","readinessPct"]},"Incident":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"organizationId":{"type":"string","format":"uuid"},"title":{"type":"string"},"description":{"type":["string","null"]},"status":{"type":"string"},"priority":{"type":["string","null"]},"category":{"type":["string","null"]},"incidentType":{"type":["string","null"]},"reportedAt":{"type":["string","null"],"format":"date-time"},"createdAt":{"type":["string","null"],"format":"date-time"},"updatedAt":{"type":["string","null"],"format":"date-time"},"resolvedAt":{"type":["string","null"],"format":"date-time"},"closedAt":{"type":["string","null"],"format":"date-time"},"dueDate":{"type":["string","null"]},"vendorId":{"type":["string","null"],"format":"uuid"},"assignedTo":{"type":["string","null"],"format":"uuid"},"reportedBy":{"type":"string","format":"uuid"},"businessImpact":{"type":["string","null"]},"affectedCustomers":{"type":["integer","null"]},"affectedSystems":{"type":["string","null"]},"affectedServices":{"type":["string","null"]},"impactAssessment":{"type":["string","null"]},"escalationLevel":{"type":["integer","null"]},"estimatedFinancialImpact":{"type":["string","null"]},"idempotencyKey":{"type":["string","null"]}},"required":["id","organizationId","title","description","status","priority","category","incidentType","reportedAt","createdAt","updatedAt","resolvedAt","closedAt","dueDate","vendorId","assignedTo","reportedBy","businessImpact","affectedCustomers","affectedSystems","affectedServices","impactAssessment","escalationLevel","estimatedFinancialImpact","idempotencyKey"],"additionalProperties":{}},"IqExtensionLogFillResult":{"type":"object","properties":{"ok":{"type":"boolean","enum":[true]}},"required":["ok"]},"IqExtensionMatchResult":{"type":"object","properties":{"question":{"type":["object","null"],"properties":{"id":{"type":"string","format":"uuid"},"importId":{"type":"string","format":"uuid"},"ordinal":{"type":"integer"},"questionText":{"type":"string"},"sourceSection":{"type":["string","null"]}},"required":["id","importId","ordinal","questionText","sourceSection"],"additionalProperties":{}},"draft":{"type":["object","null"],"properties":{"id":{"type":"string","format":"uuid"},"questionId":{"type":"string","format":"uuid"},"status":{"type":"string"},"draftAnswer":{"type":["string","null"]},"editedAnswer":{"type":["string","null"]}},"required":["id","questionId","status","draftAnswer","editedAnswer"],"additionalProperties":{}},"score":{"type":"number","minimum":0,"maximum":1}},"required":["question","draft","score"]},"Pagination":{"type":"object","properties":{"page":{"type":"integer"},"limit":{"type":"integer"},"total":{"type":"integer"},"totalPages":{"type":"integer"}},"required":["page","limit","total","totalPages"]},"Policy":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"organizationId":{"type":"string","format":"uuid"},"slug":{"type":"string"},"displayName":{"type":"string"},"category":{"type":"string"},"ownerUserId":{"type":["string","null"],"format":"uuid"},"currentVersionId":{"type":["string","null"],"format":"uuid"},"lifecycleStatus":{"type":"string"},"renewalIntervalDays":{"type":["integer","null"]},"nextRenewalAt":{"type":["string","null"],"format":"date-time"},"businessUnitIds":{"type":"array","items":{"type":"string","format":"uuid"}},"createdAt":{"type":["string","null"],"format":"date-time"},"updatedAt":{"type":["string","null"],"format":"date-time"}},"required":["id","organizationId","slug","displayName","category","ownerUserId","currentVersionId","lifecycleStatus","renewalIntervalDays","nextRenewalAt","businessUnitIds","createdAt","updatedAt"],"additionalProperties":{}},"PolicyVersion":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"policyId":{"type":"string","format":"uuid"},"versionNumber":{"type":"integer"},"locale":{"type":"string"},"title":{"type":"string"},"approvalStatus":{"type":"string"},"publishedAt":{"type":["string","null"],"format":"date-time"},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}},"required":["id","policyId","versionNumber","locale","title","approvalStatus","publishedAt","createdAt","updatedAt"],"additionalProperties":{}},"RiskRegister":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"organizationId":{"type":"string","format":"uuid"},"name":{"type":"string"},"description":{"type":["string","null"]},"isDefault":{"type":"boolean"},"scenarioSeq":{"type":"integer"},"likelihoodScale":{"type":["array","null"],"items":{"type":"object","properties":{"score":{"type":"integer","minimum":1,"maximum":5},"label":{"type":"string","minLength":1,"maxLength":100},"description":{"type":"string","maxLength":500}},"required":["score","label"]}},"impactScale":{"type":["array","null"],"items":{"type":"object","properties":{"score":{"type":"integer","minimum":1,"maximum":5},"label":{"type":"string","minLength":1,"maxLength":100},"description":{"type":"string","maxLength":500}},"required":["score","label"]}},"createdBy":{"type":["string","null"],"format":"uuid"},"createdAt":{"type":["string","null"],"format":"date-time"},"updatedAt":{"type":["string","null"],"format":"date-time"}},"required":["id","organizationId","name","description","isDefault","scenarioSeq","likelihoodScale","impactScale","createdBy","createdAt","updatedAt"]},"RiskScenario":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"organizationId":{"type":"string","format":"uuid"},"registerId":{"type":"string","format":"uuid"},"displayId":{"type":"string"},"title":{"type":"string"},"description":{"type":["string","null"]},"categoryId":{"type":["string","null"],"format":"uuid"},"riskType":{"type":["array","null"],"items":{"type":"string","enum":["confidentiality","integrity","availability"]}},"inherentLikelihood":{"type":["integer","null"]},"inherentImpact":{"type":["integer","null"]},"residualLikelihood":{"type":["integer","null"]},"residualImpact":{"type":["integer","null"]},"lifecycleStatus":{"type":"string","enum":["open","mitigating","accepted","closed"]},"approvalStatus":{"type":"string","enum":["draft","needs_review","pending_approval","approved"]},"isArchived":{"type":"boolean"},"treatment":{"type":["string","null"],"enum":["mitigate","accept","transfer","avoid",null]},"treatmentPlan":{"type":["string","null"]},"ownerUserId":{"type":["string","null"],"format":"uuid"},"targetResolutionDate":{"type":["string","null"]},"vendorId":{"type":["string","null"],"format":"uuid"},"businessFunctionId":{"type":["string","null"],"format":"uuid"},"controlId":{"type":["string","null"],"format":"uuid"},"sourceTemplateId":{"type":["string","null"],"format":"uuid"},"businessUnitIds":{"type":"array","items":{"type":"string","format":"uuid"}},"createdBy":{"type":["string","null"],"format":"uuid"},"createdAt":{"type":["string","null"],"format":"date-time"},"updatedAt":{"type":["string","null"],"format":"date-time"},"inherentScore":{"type":["integer","null"]},"residualScore":{"type":["integer","null"]}},"required":["id","organizationId","registerId","displayId","title","description","categoryId","riskType","inherentLikelihood","inherentImpact","residualLikelihood","residualImpact","lifecycleStatus","approvalStatus","isArchived","treatment","treatmentPlan","ownerUserId","targetResolutionDate","vendorId","businessFunctionId","controlId","sourceTemplateId","businessUnitIds","createdBy","createdAt","updatedAt","inherentScore","residualScore"]},"TrustCenterAccessRequest":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"organizationId":{"type":"string","format":"uuid"},"visitorEmail":{"type":"string"},"visitorName":{"type":["string","null"]},"companyName":{"type":["string","null"]},"reason":{"type":["string","null"]},"rejectionReason":{"type":["string","null"]},"status":{"type":"string"},"decidedByUserId":{"type":["string","null"],"format":"uuid"},"decidedAt":{"type":["string","null"],"format":"date-time"},"autoRuleId":{"type":["string","null"],"format":"uuid"},"visitorTokenId":{"type":["string","null"],"format":"uuid"},"requestCountryCode":{"type":["string","null"]},"requestCity":{"type":["string","null"]},"createdAt":{"type":"string","format":"date-time"}},"required":["id","organizationId","visitorEmail","visitorName","companyName","reason","rejectionReason","status","decidedByUserId","decidedAt","autoRuleId","visitorTokenId","requestCountryCode","requestCity","createdAt"],"additionalProperties":{}},"TrustCenterResource":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"organizationId":{"type":"string","format":"uuid"},"title":{"type":"string"},"description":{"type":["string","null"]},"category":{"type":"string"},"sourceType":{"type":"string"},"externalUrl":{"type":["string","null"]},"fileId":{"type":["string","null"],"format":"uuid"},"isGated":{"type":"boolean"},"isPublished":{"type":"boolean"},"sortOrder":{"type":"integer"},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}},"required":["id","organizationId","title","description","category","sourceType","externalUrl","fileId","isGated","isPublished","sortOrder","createdAt","updatedAt"],"additionalProperties":{}},"TrustCenterSubscriber":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"email":{"type":"string"},"status":{"type":"string"},"source":{"type":"string"},"scopes":{"type":"array","items":{"type":"string"}},"verifiedAt":{"type":["string","null"],"format":"date-time"},"createdAt":{"type":"string","format":"date-time"}},"required":["id","email","status","source","scopes","verifiedAt","createdAt"]},"TrustCenterVisitorToken":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"organizationId":{"type":"string","format":"uuid"},"origin":{"type":"string"},"visitorEmail":{"type":"string"},"visitorName":{"type":["string","null"]},"companyName":{"type":["string","null"]},"tokenSuffix":{"type":["string","null"]},"status":{"type":"string","enum":["active","expired","revoked"]},"expiresAt":{"type":["string","null"],"format":"date-time"},"revokedAt":{"type":["string","null"],"format":"date-time"},"lastUsedAt":{"type":["string","null"],"format":"date-time"},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}},"required":["id","organizationId","origin","visitorEmail","visitorName","companyName","tokenSuffix","status","expiresAt","revokedAt","lastUsedAt","createdAt","updatedAt"]},"UploadedFile":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"filename":{"type":"string"},"mimeType":{"type":"string"},"sizeBytes":{"type":"integer"},"contentHash":{"type":"string"},"scanStatus":{"type":"string"}},"required":["id","filename","mimeType","sizeBytes","contentHash","scanStatus"]},"Vendor":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"organizationId":{"type":"string","format":"uuid"},"displayId":{"type":["string","null"]},"name":{"type":"string"},"state":{"type":["string","null"],"enum":["procurement","active","archived",null]},"directlyEngaged":{"type":"boolean"},"vatNumber":{"type":["string","null"]},"countryCode":{"type":["string","null"]},"description":{"type":["string","null"]},"website":{"type":["string","null"]},"category":{"type":["string","null"]},"categoryId":{"type":["string","null"],"format":"uuid"},"headquartersCountryCode":{"type":["string","null"]},"authMethod":{"type":["string","null"],"enum":["sso_oidc","sso_saml","password","api_key","not_specified",null]},"servicesProvided":{"type":["string","null"]},"securityOwnerId":{"type":["string","null"],"format":"uuid"},"businessOwnerId":{"type":["string","null"],"format":"uuid"},"notes":{"type":["string","null"]},"lastAssessedAt":{"type":["string","null"],"format":"date-time"},"criticalityTierId":{"type":["string","null"],"format":"uuid"},"lei":{"type":["string","null"]},"euId":{"type":["string","null"]},"legalPersonType":{"type":["string","null"],"enum":["legal_person","natural_person",null]},"countryOfRegistration":{"type":["string","null"]},"parentLei":{"type":["string","null"]},"parentName":{"type":["string","null"]},"headOfficeAddress":{"type":["string","null"]},"inherentRiskScore":{"type":["string","null"]},"inherentRiskBand":{"type":["string","null"]},"inherentRiskScoredAt":{"type":["string","null"],"format":"date-time"},"inherentRiskApprovalStatus":{"type":"string"},"inherentRiskBandOverride":{"type":["string","null"]},"inherentRiskSignedOffAt":{"type":["string","null"],"format":"date-time"},"inherentRiskSignedOffBy":{"type":["string","null"],"format":"uuid"},"inherentRiskAnswersFingerprint":{"type":["string","null"]},"annualExpense":{"type":["string","null"]},"approvalStatus":{"type":"string"},"approvalInstanceId":{"type":["string","null"],"format":"uuid"},"businessUnitIds":{"type":"array","items":{"type":"string","format":"uuid"}},"createdAt":{"type":["string","null"],"format":"date-time"},"updatedAt":{"type":["string","null"],"format":"date-time"}},"required":["id","organizationId","displayId","name","state","directlyEngaged","vatNumber","countryCode","description","website","category","categoryId","headquartersCountryCode","authMethod","servicesProvided","securityOwnerId","businessOwnerId","notes","lastAssessedAt","criticalityTierId","lei","euId","legalPersonType","countryOfRegistration","parentLei","parentName","headOfficeAddress","inherentRiskScore","inherentRiskBand","inherentRiskScoredAt","inherentRiskApprovalStatus","inherentRiskBandOverride","inherentRiskSignedOffAt","inherentRiskSignedOffBy","inherentRiskAnswersFingerprint","annualExpense","approvalStatus","approvalInstanceId","businessUnitIds","createdAt","updatedAt"]},"VendorImportJob":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"displayId":{"type":"string"},"status":{"type":"string"},"rowsTotal":{"type":"integer"},"rowsImported":{"type":"integer"},"rowsUpdated":{"type":"integer"},"rowsSkipped":{"type":"integer"},"rowsFailed":{"type":"integer"}},"required":["id","displayId","status","rowsTotal","rowsImported","rowsUpdated","rowsSkipped","rowsFailed"],"additionalProperties":{}},"Webhook":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"organizationId":{"type":"string","format":"uuid"},"name":{"type":"string"},"trigger":{"type":"string"},"endpoint":{"type":"string","format":"uri"},"status":{"type":"string","enum":["active","disabled","suspended"]},"apiVersion":{"type":"string"},"customHeaders":{"type":"array","items":{"type":"object","properties":{"name":{"type":"string"},"valueHint":{"type":"string"}},"required":["name","valueHint"]}},"signing":{"type":"object","properties":{"enabled":{"type":"boolean"},"secretHint":{"type":["string","null"]}},"required":["enabled","secretHint"]},"consecutiveFailures":{"type":"integer"},"lastSuccessAt":{"type":["string","null"],"format":"date-time"},"lastFailureAt":{"type":["string","null"],"format":"date-time"},"disabledReason":{"type":["string","null"]},"createdAt":{"type":["string","null"],"format":"date-time"},"updatedAt":{"type":["string","null"],"format":"date-time"}},"required":["id","organizationId","name","trigger","endpoint","status","apiVersion","customHeaders","signing","consecutiveFailures","lastSuccessAt","lastFailureAt","disabledReason","createdAt","updatedAt"]},"WebhookCreateResult":{"type":"object","properties":{"webhook":{"$ref":"#/components/schemas/Webhook"},"signingSecret":{"type":"string"}},"required":["webhook"]},"WebhookDelivery":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"webhookId":{"type":"string","format":"uuid"},"trigger":{"type":"string"},"apiVersion":{"type":"string"},"status":{"type":"string","enum":["pending","succeeded","failed"]},"payload":{"type":"object","additionalProperties":{}},"responseStatus":{"type":["integer","null"]},"errorMessage":{"type":["string","null"]},"durationMs":{"type":["integer","null"]},"sentAt":{"type":["string","null"],"format":"date-time"},"isReplay":{"type":"boolean"},"replayOfDeliveryId":{"type":["string","null"],"format":"uuid"},"createdAt":{"type":["string","null"],"format":"date-time"}},"required":["id","webhookId","trigger","apiVersion","status","payload","responseStatus","errorMessage","durationMs","sentAt","isReplay","replayOfDeliveryId","createdAt"]},"WebhookTrigger":{"type":"object","properties":{"trigger":{"type":"string"},"description":{"type":"string"},"tier":{"type":"string","enum":["core","premium"]},"status":{"type":"string","enum":["active","deprecated","removed"]},"entitled":{"type":"boolean"}},"required":["trigger","description","tier","status","entitled"]}},"parameters":{},"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"vnd_live_<base62>","description":"API key issued from Settings → API clients."}}},"paths":{"/audit-log":{"get":{"operationId":"getAuditLog","tags":["Audit"],"summary":"List audit-log entries (cursor-paginated)","description":"Cursor-paginated read of the hash-chained audit trail. Pass `?cursor=<opaque>&limit=<n>` to advance; the response carries `cursor.nextCursor` (null on the last page) plus `cursor.hasMore`. The legacy `?page=` parameter returns 400 — see /v1/openapi.json for the canonical contract.","security":[{"bearerAuth":["audit:read"]}],"parameters":[{"schema":{"type":"string"},"required":false,"name":"entityType","in":"query"},{"schema":{"type":"string"},"required":false,"name":"entityId","in":"query"},{"schema":{"type":"string"},"required":false,"name":"operation","in":"query"},{"schema":{"type":"string"},"required":false,"name":"userId","in":"query"},{"schema":{"type":"string"},"required":false,"name":"createdFrom","in":"query"},{"schema":{"type":"string"},"required":false,"name":"createdTo","in":"query"},{"schema":{"type":"string"},"required":false,"name":"dateFrom","in":"query"},{"schema":{"type":"string"},"required":false,"name":"dateTo","in":"query"},{"schema":{"type":"string","enum":["info","warning","error","critical"]},"required":false,"name":"severity","in":"query"},{"schema":{"type":"string"},"required":false,"name":"ipAddress","in":"query"},{"schema":{"type":"string","minLength":1},"required":false,"name":"cursor","in":"query"},{"schema":{"type":"integer","minimum":1,"maximum":500,"default":50},"required":false,"name":"limit","in":"query"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","enum":[true]},"data":{"type":"array","items":{"$ref":"#/components/schemas/AuditLogEntry"}},"timestamp":{"type":"string","format":"date-time"},"requestId":{"type":"string"},"message":{"type":"string"},"cursor":{"$ref":"#/components/schemas/CursorMeta"}},"required":["success","data","timestamp","cursor"]},"example":{"success":true,"data":[{"id":"947f0edf-a104-45e7-8dec-65ecc3246c38","entityType":"string","entityId":"string","operation":"string","oldValues":{},"newValues":{},"changedFields":["string"],"userId":"string","userEmail":"string","userRole":"string","ipAddress":"string","userAgent":"string","requestId":"req_01J5X8ZC3K4T7Q9M2W6B0N1V4H","description":"string","severity":"string","createdAt":"2026-08-19T09:41:12.004Z"}],"timestamp":"2026-08-19T09:41:12.004Z","requestId":"req_01J5X8ZC3K4T7Q9M2W6B0N1V4H","message":"string","cursor":{"nextCursor":"string","hasMore":true,"limit":1}}}}},"400":{"description":"Validation error","content":{"application/json":{"example":{"success":false,"error":"Bad request","code":"BAD_REQUEST","timestamp":"2026-08-19T09:41:12.004Z","requestId":"req_01J5X8ZC3K4T7Q9M2W6B0N1V4H"},"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Unauthorized","content":{"application/json":{"example":{"success":false,"error":"Unauthorized","code":"UNAUTHORIZED","timestamp":"2026-08-19T09:41:12.004Z","requestId":"req_01J5X8ZC3K4T7Q9M2W6B0N1V4H"},"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Forbidden — missing scope","content":{"application/json":{"example":{"success":false,"error":"Forbidden","code":"FORBIDDEN","timestamp":"2026-08-19T09:41:12.004Z","requestId":"req_01J5X8ZC3K4T7Q9M2W6B0N1V4H"},"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not found","content":{"application/json":{"example":{"success":false,"error":"Resource not found","code":"NOT_FOUND","timestamp":"2026-08-19T09:41:12.004Z","requestId":"req_01J5X8ZC3K4T7Q9M2W6B0N1V4H"},"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limit exceeded","content":{"application/json":{"example":{"success":false,"error":"Too many requests","code":"TOO_MANY_REQUESTS","timestamp":"2026-08-19T09:41:12.004Z","requestId":"req_01J5X8ZC3K4T7Q9M2W6B0N1V4H"},"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/compliance/frameworks/{code}":{"get":{"operationId":"getComplianceFrameworksByCode","tags":["Compliance"],"summary":"Get a framework breakdown","description":"The per-category and per-citation breakdown for one framework, addressed by CODE (`dora`, `nis2`, `iso27001-2022`, `soc2`, …) rather than by the per-environment uuid. `byCitation` names the controls mapped to each article, which is what turns \"we are 78% ready\" into a list of what is missing. An unknown code is a 404.","security":[{"bearerAuth":["compliance:read"]}],"parameters":[{"schema":{"type":"string","minLength":1,"maxLength":50},"required":true,"name":"code","in":"path"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","enum":[true]},"data":{"$ref":"#/components/schemas/FrameworkBreakdown"},"timestamp":{"type":"string","format":"date-time"},"requestId":{"type":"string"},"message":{"type":"string"}},"required":["success","data","timestamp"]},"example":{"success":true,"data":{"overall":{"frameworkId":"30f00833-3adc-4523-89bc-b160f80b406c","code":"string","name":"string","controlsTotal":1,"controlsOk":1,"controlsNeedsEvidence":1,"controlsExpiringSoon":1,"controlsExpired":1,"controlsDeactivated":1,"readinessPct":1},"byCategory":[{"category":"string","controlsTotal":1,"controlsOk":1,"readinessPct":1}],"byCitation":[{"citationId":"296381d3-f8a5-4c03-8c4f-d40085aac24c","articleRef":"string","title":"string","mappedControls":[{"controlId":"22050386-11e4-48cc-89c3-5ddd078cbc9b","displayId":"string","name":"string","status":"string"}]}]},"timestamp":"2026-08-19T09:41:12.004Z","requestId":"req_01J5X8ZC3K4T7Q9M2W6B0N1V4H","message":"string"}}}},"400":{"description":"Validation error","content":{"application/json":{"example":{"success":false,"error":"Bad request","code":"BAD_REQUEST","timestamp":"2026-08-19T09:41:12.004Z","requestId":"req_01J5X8ZC3K4T7Q9M2W6B0N1V4H"},"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Unauthorized","content":{"application/json":{"example":{"success":false,"error":"Unauthorized","code":"UNAUTHORIZED","timestamp":"2026-08-19T09:41:12.004Z","requestId":"req_01J5X8ZC3K4T7Q9M2W6B0N1V4H"},"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Forbidden — missing scope","content":{"application/json":{"example":{"success":false,"error":"Forbidden","code":"FORBIDDEN","timestamp":"2026-08-19T09:41:12.004Z","requestId":"req_01J5X8ZC3K4T7Q9M2W6B0N1V4H"},"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"No framework with that code","content":{"application/json":{"example":{"success":false,"error":"Resource not found","code":"NOT_FOUND","timestamp":"2026-08-19T09:41:12.004Z","requestId":"req_01J5X8ZC3K4T7Q9M2W6B0N1V4H"},"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limit exceeded","content":{"application/json":{"example":{"success":false,"error":"Too many requests","code":"TOO_MANY_REQUESTS","timestamp":"2026-08-19T09:41:12.004Z","requestId":"req_01J5X8ZC3K4T7Q9M2W6B0N1V4H"},"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/compliance/posture":{"get":{"operationId":"getCompliancePosture","tags":["Compliance"],"summary":"Get compliance posture","description":"The organization's overall readiness score plus one score per ADOPTED framework. Only `active` adoptions contribute — a framework the organization has paused or stepped away from is excluded rather than counted as failing, because a score that punishes a deliberate de-adoption reports a decision as a problem.","security":[{"bearerAuth":["compliance:read"]}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","enum":[true]},"data":{"$ref":"#/components/schemas/CompliancePosture"},"timestamp":{"type":"string","format":"date-time"},"requestId":{"type":"string"},"message":{"type":"string"}},"required":["success","data","timestamp"]},"example":{"success":true,"data":{"overallScore":1,"byFramework":[{"frameworkId":"2f2d0a0e-4fe6-40e4-8f5a-dba5ad07be73","code":"string","name":"string","controlsTotal":1,"controlsOk":1,"controlsNeedsEvidence":1,"controlsExpiringSoon":1,"controlsExpired":1,"controlsDeactivated":1,"readinessPct":1}]},"timestamp":"2026-08-19T09:41:12.004Z","requestId":"req_01J5X8ZC3K4T7Q9M2W6B0N1V4H","message":"string"}}}},"400":{"description":"Validation error","content":{"application/json":{"example":{"success":false,"error":"Bad request","code":"BAD_REQUEST","timestamp":"2026-08-19T09:41:12.004Z","requestId":"req_01J5X8ZC3K4T7Q9M2W6B0N1V4H"},"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Unauthorized","content":{"application/json":{"example":{"success":false,"error":"Unauthorized","code":"UNAUTHORIZED","timestamp":"2026-08-19T09:41:12.004Z","requestId":"req_01J5X8ZC3K4T7Q9M2W6B0N1V4H"},"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Forbidden — missing scope","content":{"application/json":{"example":{"success":false,"error":"Forbidden","code":"FORBIDDEN","timestamp":"2026-08-19T09:41:12.004Z","requestId":"req_01J5X8ZC3K4T7Q9M2W6B0N1V4H"},"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not found","content":{"application/json":{"example":{"success":false,"error":"Resource not found","code":"NOT_FOUND","timestamp":"2026-08-19T09:41:12.004Z","requestId":"req_01J5X8ZC3K4T7Q9M2W6B0N1V4H"},"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limit exceeded","content":{"application/json":{"example":{"success":false,"error":"Too many requests","code":"TOO_MANY_REQUESTS","timestamp":"2026-08-19T09:41:12.004Z","requestId":"req_01J5X8ZC3K4T7Q9M2W6B0N1V4H"},"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/contracts":{"get":{"operationId":"getContracts","tags":["Contracts"],"summary":"List contracts","security":[{"bearerAuth":["contracts:read"]}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","enum":[true]},"data":{"type":"array","items":{"$ref":"#/components/schemas/Contract"}},"timestamp":{"type":"string","format":"date-time"},"requestId":{"type":"string"},"message":{"type":"string"},"pagination":{"$ref":"#/components/schemas/Pagination"}},"required":["success","data","timestamp"]},"example":{"success":true,"data":[{"id":"52323f18-7f19-45ee-81e2-44170a3129e9","vendorId":"1348a75a-b35f-4f88-8a3c-97d19263044f","title":"string","contractType":"string","contractTypeId":"7c98560e-2fcf-44e4-8a95-07a5a99b0273","startDate":"string","endDate":"string","value":"string","currency":"string","status":"string","contractStatusId":"732311ac-ee34-44ea-862b-2acb24f463dd","riskNotes":"string","arrangementReference":"string","isIntragroup":true,"clientNoticePeriodDays":1,"vendorNoticePeriodDays":1,"terminationDate":"string","signingDate":"string","governingLaw":"string","storesData":true,"dataSensitivity":"low","relianceLevel":"none","dataLocationAtRest":["string"],"dataProcessingLocation":["string"],"outsourcingClassification":"outsourcing","outsourcingClassificationRationale":"string","involvesPersonalData":true,"nextRenewalDate":"string","cloudServiceModel":"iaas","cloudDeploymentModel":"public","lastAuditDate":"string","nextAuditDate":"string","alternativeProvidersIdentified":true,"alternativeProvidersNotes":"string","ebaArrangementType":"eba_CO:x1","businessOwnerId":"e6d96007-6d32-47df-81f4-bf54a4492af0","approvalStatus":"string","approvalInstanceId":"37eed670-7efb-4576-8b0c-472f7f5408b1","businessUnitIds":["fed72751-7fb2-47a9-80a2-b09eaa1c026e"],"createdAt":"2026-08-19T09:41:12.004Z","updatedAt":"2026-08-19T09:41:12.004Z","statusPhase":"draft","vendor":{"id":"e302ada8-0737-429e-8930-3d2769f03e19","name":"string"},"businessOwner":{"id":"b60c8823-b6ba-4bf3-8745-8ad0f6798bbc","firstName":"string","lastName":"string","email":"string"}}],"timestamp":"2026-08-19T09:41:12.004Z","requestId":"req_01J5X8ZC3K4T7Q9M2W6B0N1V4H","message":"string","pagination":{"page":1,"limit":1,"total":1,"totalPages":1}}}}},"400":{"description":"Validation error","content":{"application/json":{"example":{"success":false,"error":"Bad request","code":"BAD_REQUEST","timestamp":"2026-08-19T09:41:12.004Z","requestId":"req_01J5X8ZC3K4T7Q9M2W6B0N1V4H"},"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Unauthorized","content":{"application/json":{"example":{"success":false,"error":"Unauthorized","code":"UNAUTHORIZED","timestamp":"2026-08-19T09:41:12.004Z","requestId":"req_01J5X8ZC3K4T7Q9M2W6B0N1V4H"},"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Forbidden — missing scope","content":{"application/json":{"example":{"success":false,"error":"Forbidden","code":"FORBIDDEN","timestamp":"2026-08-19T09:41:12.004Z","requestId":"req_01J5X8ZC3K4T7Q9M2W6B0N1V4H"},"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not found","content":{"application/json":{"example":{"success":false,"error":"Resource not found","code":"NOT_FOUND","timestamp":"2026-08-19T09:41:12.004Z","requestId":"req_01J5X8ZC3K4T7Q9M2W6B0N1V4H"},"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limit exceeded","content":{"application/json":{"example":{"success":false,"error":"Too many requests","code":"TOO_MANY_REQUESTS","timestamp":"2026-08-19T09:41:12.004Z","requestId":"req_01J5X8ZC3K4T7Q9M2W6B0N1V4H"},"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/contracts/documents/{docId}/download":{"get":{"operationId":"getContractsDocumentsByDocIdDownload","tags":["Contracts"],"summary":"Download a contract document","description":"Streams the stored bytes with `Content-Disposition: attachment` — not the JSON envelope.","security":[{"bearerAuth":["contracts:read"]}],"parameters":[{"schema":{"type":"string","format":"uuid"},"required":true,"name":"docId","in":"path"}],"responses":{"200":{"description":"The document bytes","content":{"application/json":{"schema":{"type":"string","format":"binary"},"example":"<binary>"}}},"400":{"description":"Validation error","content":{"application/json":{"example":{"success":false,"error":"Bad request","code":"BAD_REQUEST","timestamp":"2026-08-19T09:41:12.004Z","requestId":"req_01J5X8ZC3K4T7Q9M2W6B0N1V4H"},"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Unauthorized","content":{"application/json":{"example":{"success":false,"error":"Unauthorized","code":"UNAUTHORIZED","timestamp":"2026-08-19T09:41:12.004Z","requestId":"req_01J5X8ZC3K4T7Q9M2W6B0N1V4H"},"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Forbidden — missing scope","content":{"application/json":{"example":{"success":false,"error":"Forbidden","code":"FORBIDDEN","timestamp":"2026-08-19T09:41:12.004Z","requestId":"req_01J5X8ZC3K4T7Q9M2W6B0N1V4H"},"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not found","content":{"application/json":{"example":{"success":false,"error":"Resource not found","code":"NOT_FOUND","timestamp":"2026-08-19T09:41:12.004Z","requestId":"req_01J5X8ZC3K4T7Q9M2W6B0N1V4H"},"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limit exceeded","content":{"application/json":{"example":{"success":false,"error":"Too many requests","code":"TOO_MANY_REQUESTS","timestamp":"2026-08-19T09:41:12.004Z","requestId":"req_01J5X8ZC3K4T7Q9M2W6B0N1V4H"},"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"503":{"description":"Object storage not configured","content":{"application/json":{"example":{"success":false,"error":"Service unavailable","code":"SERVICE_UNAVAILABLE","timestamp":"2026-08-19T09:41:12.004Z","requestId":"req_01J5X8ZC3K4T7Q9M2W6B0N1V4H"},"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/contracts/{id}":{"get":{"operationId":"getContractsById","tags":["Contracts"],"summary":"Get a contract by id","security":[{"bearerAuth":["contracts:read"]}],"parameters":[{"schema":{"type":"string","format":"uuid"},"required":true,"name":"id","in":"path"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","enum":[true]},"data":{"$ref":"#/components/schemas/Contract"},"timestamp":{"type":"string","format":"date-time"},"requestId":{"type":"string"},"message":{"type":"string"}},"required":["success","data","timestamp"]},"example":{"success":true,"data":{"id":"470f0b70-4eaf-4476-8284-042f10d28fb1","vendorId":"3488bd12-c341-4030-834f-304932a90937","title":"string","contractType":"string","contractTypeId":"85d58cb6-632c-4f5c-8e0c-828df6b17dab","startDate":"string","endDate":"string","value":"string","currency":"string","status":"string","contractStatusId":"4c2e16a4-928d-4752-85fe-6483f6784085","riskNotes":"string","arrangementReference":"string","isIntragroup":true,"clientNoticePeriodDays":1,"vendorNoticePeriodDays":1,"terminationDate":"string","signingDate":"string","governingLaw":"string","storesData":true,"dataSensitivity":"low","relianceLevel":"none","dataLocationAtRest":["string"],"dataProcessingLocation":["string"],"outsourcingClassification":"outsourcing","outsourcingClassificationRationale":"string","involvesPersonalData":true,"nextRenewalDate":"string","cloudServiceModel":"iaas","cloudDeploymentModel":"public","lastAuditDate":"string","nextAuditDate":"string","alternativeProvidersIdentified":true,"alternativeProvidersNotes":"string","ebaArrangementType":"eba_CO:x1","businessOwnerId":"99b4e72f-24c7-4bd7-8ab8-3ebca80abba8","approvalStatus":"string","approvalInstanceId":"f2c20a58-8176-4bae-8a39-2157baef75a9","businessUnitIds":["6c8ec2d9-bfbc-4ec1-8820-4b66dcd6ab46"],"createdAt":"2026-08-19T09:41:12.004Z","updatedAt":"2026-08-19T09:41:12.004Z","statusPhase":"draft","vendor":{"id":"cb6b7120-5c23-4886-803f-995f6f1e6a41","name":"string"},"businessOwner":{"id":"69178eeb-5915-48cb-8596-a2d8a8226054","firstName":"string","lastName":"string","email":"string"}},"timestamp":"2026-08-19T09:41:12.004Z","requestId":"req_01J5X8ZC3K4T7Q9M2W6B0N1V4H","message":"string"}}}},"400":{"description":"Validation error","content":{"application/json":{"example":{"success":false,"error":"Bad request","code":"BAD_REQUEST","timestamp":"2026-08-19T09:41:12.004Z","requestId":"req_01J5X8ZC3K4T7Q9M2W6B0N1V4H"},"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Unauthorized","content":{"application/json":{"example":{"success":false,"error":"Unauthorized","code":"UNAUTHORIZED","timestamp":"2026-08-19T09:41:12.004Z","requestId":"req_01J5X8ZC3K4T7Q9M2W6B0N1V4H"},"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Forbidden — missing scope","content":{"application/json":{"example":{"success":false,"error":"Forbidden","code":"FORBIDDEN","timestamp":"2026-08-19T09:41:12.004Z","requestId":"req_01J5X8ZC3K4T7Q9M2W6B0N1V4H"},"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not found","content":{"application/json":{"example":{"success":false,"error":"Resource not found","code":"NOT_FOUND","timestamp":"2026-08-19T09:41:12.004Z","requestId":"req_01J5X8ZC3K4T7Q9M2W6B0N1V4H"},"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limit exceeded","content":{"application/json":{"example":{"success":false,"error":"Too many requests","code":"TOO_MANY_REQUESTS","timestamp":"2026-08-19T09:41:12.004Z","requestId":"req_01J5X8ZC3K4T7Q9M2W6B0N1V4H"},"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/contracts/{id}/documents":{"post":{"operationId":"postContractsByIdDocuments","tags":["Contracts"],"summary":"Upload a document to a contract","description":"Files a document (agreement, DPA, SLA, order form, amendment, exit plan) against an existing contract. `supersedesDocumentId` stamps the document it replaces in the same transaction, and a replacement inherits the type it replaces unless `docType` says otherwise. Naming a supersession target disables the content replay — it is an instruction about the register, not a retry. Idempotent on content: if the target already carries CURRENT bytes with this hash, the existing record is returned with 200 and `Idempotent-Replay: true` instead of filing a duplicate. Sending `X-Checksum-Sha256` lets that be answered BEFORE the body is transferred, which is what makes a interrupted bulk run cheap to resume. The response `file.scanStatus` reports the asynchronous malware-scan state — a document is not necessarily downloadable the moment this returns.","security":[{"bearerAuth":["contracts:write"]}],"parameters":[{"schema":{"type":"string","format":"uuid"},"required":true,"name":"id","in":"path"},{"schema":{"type":"string"},"required":false,"name":"filename","in":"query"},{"schema":{"type":"string"},"required":false,"name":"docType","in":"query"},{"schema":{"type":"string","format":"uuid"},"required":false,"name":"supersedesDocumentId","in":"query"}],"requestBody":{"description":"Either `multipart/form-data` with a `file` part (metadata in sibling text fields), or a raw `application/octet-stream` body (metadata in the query string, filename via `?filename=`, `X-Filename` or `Content-Disposition`). Raw bodies MUST send `Content-Length`. Optional `X-Checksum-Sha256` is verified against the stored bytes; on mismatch nothing is written.","required":true,"content":{"multipart/form-data":{"schema":{"type":"object","properties":{"file":{"type":"string","format":"binary"},"docType":{"type":"string"},"supersedesDocumentId":{"type":"string"}},"required":["file"]}},"application/octet-stream":{"schema":{"type":"string","format":"binary"}}}},"responses":{"201":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","enum":[true]},"data":{"$ref":"#/components/schemas/ContractDocument"},"timestamp":{"type":"string","format":"date-time"},"requestId":{"type":"string"},"message":{"type":"string"}},"required":["success","data","timestamp"]},"example":{"success":true,"data":{"id":"107f33ba-b03e-4aa8-8d41-eb3143c5446f","contractId":"19446614-dcac-44a2-84e0-5973242cd655","docType":"string","fileId":"fb1348a8-e95b-439e-87dd-d027552ea719","filename":"string","mimeType":"string","sizeBytes":1,"scanStatus":"string","addedByUserId":"881ac022-621c-4260-85c8-11d966f41ee7","createdAt":"2026-08-19T09:41:12.004Z","supersededById":"d903bf39-dbe6-49e1-8d21-8ec66dd3bb66","supersededAt":"2026-08-19T09:41:12.004Z"},"timestamp":"2026-08-19T09:41:12.004Z","requestId":"req_01J5X8ZC3K4T7Q9M2W6B0N1V4H","message":"string"}}}},"400":{"description":"Validation error","content":{"application/json":{"example":{"success":false,"error":"Bad request","code":"BAD_REQUEST","timestamp":"2026-08-19T09:41:12.004Z","requestId":"req_01J5X8ZC3K4T7Q9M2W6B0N1V4H"},"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Unauthorized","content":{"application/json":{"example":{"success":false,"error":"Unauthorized","code":"UNAUTHORIZED","timestamp":"2026-08-19T09:41:12.004Z","requestId":"req_01J5X8ZC3K4T7Q9M2W6B0N1V4H"},"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"402":{"description":"Storage quota exhausted for the organization plan","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Forbidden — missing scope","content":{"application/json":{"example":{"success":false,"error":"Forbidden","code":"FORBIDDEN","timestamp":"2026-08-19T09:41:12.004Z","requestId":"req_01J5X8ZC3K4T7Q9M2W6B0N1V4H"},"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not found","content":{"application/json":{"example":{"success":false,"error":"Resource not found","code":"NOT_FOUND","timestamp":"2026-08-19T09:41:12.004Z","requestId":"req_01J5X8ZC3K4T7Q9M2W6B0N1V4H"},"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"411":{"description":"Content-Length is required for a raw (non-multipart) body","content":{"application/json":{"example":{"success":false,"error":"Content-Length is required for this upload","code":"LENGTH_REQUIRED","timestamp":"2026-08-19T09:41:12.004Z","requestId":"req_01J5X8ZC3K4T7Q9M2W6B0N1V4H"},"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"413":{"description":"Upload exceeds API_UPLOAD_MAX_BYTES (details.maxBytes)","content":{"application/json":{"example":{"success":false,"error":"Upload exceeds the maximum allowed size","code":"PAYLOAD_TOO_LARGE","details":{"maxBytes":262144000},"timestamp":"2026-08-19T09:41:12.004Z","requestId":"req_01J5X8ZC3K4T7Q9M2W6B0N1V4H"},"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"422":{"description":"Rejected file type, unverifiable content, or checksum mismatch","content":{"application/json":{"example":{"success":false,"error":"Validation failed","code":"VALIDATION_ERROR","timestamp":"2026-08-19T09:41:12.004Z","requestId":"req_01J5X8ZC3K4T7Q9M2W6B0N1V4H"},"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limit exceeded","content":{"application/json":{"example":{"success":false,"error":"Too many requests","code":"TOO_MANY_REQUESTS","timestamp":"2026-08-19T09:41:12.004Z","requestId":"req_01J5X8ZC3K4T7Q9M2W6B0N1V4H"},"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"503":{"description":"Object storage not configured","content":{"application/json":{"example":{"success":false,"error":"Service unavailable","code":"SERVICE_UNAVAILABLE","timestamp":"2026-08-19T09:41:12.004Z","requestId":"req_01J5X8ZC3K4T7Q9M2W6B0N1V4H"},"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}},"get":{"operationId":"getContractsByIdDocuments","tags":["Contracts"],"summary":"List a contract's documents","description":"Current documents only. `?includeSuperseded=true` adds the ones later uploads replaced — a superseded agreement must never appear beside the live one with nothing distinguishing them.","security":[{"bearerAuth":["contracts:read"]}],"parameters":[{"schema":{"type":"string","format":"uuid"},"required":true,"name":"id","in":"path"},{"schema":{"type":"string","enum":["true","false"]},"required":false,"name":"includeSuperseded","in":"query"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","enum":[true]},"data":{"type":"array","items":{"$ref":"#/components/schemas/ContractDocument"}},"timestamp":{"type":"string","format":"date-time"},"requestId":{"type":"string"},"message":{"type":"string"}},"required":["success","data","timestamp"]},"example":{"success":true,"data":[{"id":"22645569-8ef2-4771-89b2-087605434b76","contractId":"f1954f47-930b-499f-878e-6094a52202b0","docType":"string","fileId":"f99dfa3f-30b0-4e07-8a86-b04cba078158","filename":"string","mimeType":"string","sizeBytes":1,"scanStatus":"string","addedByUserId":"b7c06ef7-38ee-4baf-8bb8-3fc4f30c5b40","createdAt":"2026-08-19T09:41:12.004Z","supersededById":"403c6db6-d320-425c-8b78-cb8da82868ab","supersededAt":"2026-08-19T09:41:12.004Z"}],"timestamp":"2026-08-19T09:41:12.004Z","requestId":"req_01J5X8ZC3K4T7Q9M2W6B0N1V4H","message":"string"}}}},"400":{"description":"Validation error","content":{"application/json":{"example":{"success":false,"error":"Bad request","code":"BAD_REQUEST","timestamp":"2026-08-19T09:41:12.004Z","requestId":"req_01J5X8ZC3K4T7Q9M2W6B0N1V4H"},"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Unauthorized","content":{"application/json":{"example":{"success":false,"error":"Unauthorized","code":"UNAUTHORIZED","timestamp":"2026-08-19T09:41:12.004Z","requestId":"req_01J5X8ZC3K4T7Q9M2W6B0N1V4H"},"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Forbidden — missing scope","content":{"application/json":{"example":{"success":false,"error":"Forbidden","code":"FORBIDDEN","timestamp":"2026-08-19T09:41:12.004Z","requestId":"req_01J5X8ZC3K4T7Q9M2W6B0N1V4H"},"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not found","content":{"application/json":{"example":{"success":false,"error":"Resource not found","code":"NOT_FOUND","timestamp":"2026-08-19T09:41:12.004Z","requestId":"req_01J5X8ZC3K4T7Q9M2W6B0N1V4H"},"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limit exceeded","content":{"application/json":{"example":{"success":false,"error":"Too many requests","code":"TOO_MANY_REQUESTS","timestamp":"2026-08-19T09:41:12.004Z","requestId":"req_01J5X8ZC3K4T7Q9M2W6B0N1V4H"},"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/controls":{"get":{"operationId":"getControls","tags":["Controls"],"summary":"List controls","description":"The organization's control register, offset-paginated. Filter by `status`, `domain`, `frameworkCode` (repeatable — `?frameworkCode=dora,nis2` and the repeated form both work) and `ownerUserId`, or pass `hasOwner=false` for the accountability-gap query: controls with nobody assigned. `frameworkCode` values are DATA (`reg_frameworks.code`), so an unknown code matches no mapping and honestly returns nothing rather than erroring.","security":[{"bearerAuth":["controls:read"]}],"parameters":[{"schema":{"type":"integer","minimum":1,"maximum":10000,"default":1},"required":false,"name":"page","in":"query"},{"schema":{"type":"integer","minimum":1,"maximum":500,"default":100},"required":false,"name":"limit","in":"query"},{"schema":{"type":"string","enum":["name","displayId","status","effectiveDate","createdAt","updatedAt"]},"required":false,"name":"sortBy","in":"query"},{"schema":{"type":"string","enum":["asc","desc"],"default":"desc"},"required":false,"name":"sortOrder","in":"query"},{"schema":{"type":"string","minLength":1,"maxLength":255},"required":false,"name":"search","in":"query"},{"schema":{"type":["array","null"],"items":{"type":"string","minLength":1,"maxLength":50},"maxItems":100},"required":false,"name":"frameworkCode","in":"query"},{"schema":{"type":"string","format":"uuid"},"required":false,"name":"ownerUserId","in":"query"},{"schema":{"type":["string","null"],"enum":["true","false","all",null]},"required":false,"name":"hasOwner","in":"query"},{"schema":{"type":["array","null"],"items":{"type":"string","enum":["ok","needs_evidence","expiring_soon","expired","deactivated"]},"maxItems":100},"required":false,"name":"status","in":"query"},{"schema":{"type":["array","null"],"items":{"type":"string","minLength":1,"maxLength":50,"pattern":"^[a-z0-9][a-z0-9_]*$"},"maxItems":100},"required":false,"name":"domain","in":"query"},{"schema":{"type":"string","format":"uuid"},"required":false,"name":"businessUnitId","in":"query"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","enum":[true]},"data":{"type":"array","items":{"$ref":"#/components/schemas/Control"}},"timestamp":{"type":"string","format":"date-time"},"requestId":{"type":"string"},"message":{"type":"string"},"pagination":{"$ref":"#/components/schemas/Pagination"}},"required":["success","data","timestamp"]},"example":{"success":true,"data":[{"id":"6a29a939-5a95-47e1-8b32-88c6b28d4966","organizationId":"70377764-0d50-4592-8772-9343805dd8c5","displayId":"string","name":"string","description":"string","status":"string","domain":"string","ownerUserId":"b390946b-1599-414b-88d8-e458096f7cd4","effectiveDate":"string","createdAt":"2026-08-19T09:41:12.004Z","updatedAt":"2026-08-19T09:41:12.004Z"}],"timestamp":"2026-08-19T09:41:12.004Z","requestId":"req_01J5X8ZC3K4T7Q9M2W6B0N1V4H","message":"string","pagination":{"page":1,"limit":1,"total":1,"totalPages":1}}}}},"400":{"description":"Validation error","content":{"application/json":{"example":{"success":false,"error":"Bad request","code":"BAD_REQUEST","timestamp":"2026-08-19T09:41:12.004Z","requestId":"req_01J5X8ZC3K4T7Q9M2W6B0N1V4H"},"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Unauthorized","content":{"application/json":{"example":{"success":false,"error":"Unauthorized","code":"UNAUTHORIZED","timestamp":"2026-08-19T09:41:12.004Z","requestId":"req_01J5X8ZC3K4T7Q9M2W6B0N1V4H"},"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Forbidden — missing scope","content":{"application/json":{"example":{"success":false,"error":"Forbidden","code":"FORBIDDEN","timestamp":"2026-08-19T09:41:12.004Z","requestId":"req_01J5X8ZC3K4T7Q9M2W6B0N1V4H"},"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not found","content":{"application/json":{"example":{"success":false,"error":"Resource not found","code":"NOT_FOUND","timestamp":"2026-08-19T09:41:12.004Z","requestId":"req_01J5X8ZC3K4T7Q9M2W6B0N1V4H"},"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limit exceeded","content":{"application/json":{"example":{"success":false,"error":"Too many requests","code":"TOO_MANY_REQUESTS","timestamp":"2026-08-19T09:41:12.004Z","requestId":"req_01J5X8ZC3K4T7Q9M2W6B0N1V4H"},"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/controls/{controlId}/evidence":{"post":{"operationId":"postControlsByControlIdEvidence","tags":["Evidence"],"summary":"Upload evidence to a control","description":"Streams a document into the control as its current evidence, superseding whatever it replaces — the same lifecycle as the app. Idempotent on content: if the target already carries CURRENT bytes with this hash, the existing record is returned with 200 and `Idempotent-Replay: true` instead of filing a duplicate. Sending `X-Checksum-Sha256` lets that be answered BEFORE the body is transferred, which is what makes a interrupted bulk run cheap to resume. The response `file.scanStatus` reports the asynchronous malware-scan state — a document is not necessarily downloadable the moment this returns.","security":[{"bearerAuth":["evidence:write"]}],"parameters":[{"schema":{"type":"string","format":"uuid"},"required":true,"name":"controlId","in":"path"},{"schema":{"type":"string"},"required":false,"name":"filename","in":"query"},{"schema":{"type":"string"},"required":false,"name":"summary","in":"query"},{"schema":{"type":"string"},"required":false,"name":"description","in":"query"},{"schema":{"type":"string"},"required":false,"name":"effectiveDate","in":"query"},{"schema":{"type":"string","enum":["true","false"]},"required":false,"name":"isSensitive","in":"query"}],"requestBody":{"description":"Either `multipart/form-data` with a `file` part (metadata in sibling text fields), or a raw `application/octet-stream` body (metadata in the query string, filename via `?filename=`, `X-Filename` or `Content-Disposition`). Raw bodies MUST send `Content-Length`. Optional `X-Checksum-Sha256` is verified against the stored bytes; on mismatch nothing is written.","required":true,"content":{"multipart/form-data":{"schema":{"type":"object","properties":{"file":{"type":"string","format":"binary"},"summary":{"type":"string"},"description":{"type":"string"},"effectiveDate":{"type":"string"},"isSensitive":{"type":"string"}},"required":["file"]}},"application/octet-stream":{"schema":{"type":"string","format":"binary"}}}},"responses":{"201":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","enum":[true]},"data":{"$ref":"#/components/schemas/EvidenceUpload"},"timestamp":{"type":"string","format":"date-time"},"requestId":{"type":"string"},"message":{"type":"string"}},"required":["success","data","timestamp"]},"example":{"success":true,"data":{"evidence":{"id":"821d0c28-fdba-461e-8909-ffa75dbd6d99","organizationId":"04d3036d-072e-47bd-8c0d-501a16f51f3a","controlId":"2ab81157-94c3-48cf-8b6b-9924ea620d60","controlDisplayId":"string","controlName":"string","testType":"string","source":"string","status":"string","summary":"string","isSensitive":true,"collectedAt":"2026-08-19T09:41:12.004Z","expiresAt":"2026-08-19T09:41:12.004Z","supersededBy":"a6bfe6d0-5218-4c96-8159-be8f1b46f4d1"},"file":{"id":"6f552bf3-3414-4c63-8bc1-db20962bf9ac","filename":"string","mimeType":"string","sizeBytes":1,"contentHash":"string","scanStatus":"string"}},"timestamp":"2026-08-19T09:41:12.004Z","requestId":"req_01J5X8ZC3K4T7Q9M2W6B0N1V4H","message":"string"}}}},"400":{"description":"Validation error","content":{"application/json":{"example":{"success":false,"error":"Bad request","code":"BAD_REQUEST","timestamp":"2026-08-19T09:41:12.004Z","requestId":"req_01J5X8ZC3K4T7Q9M2W6B0N1V4H"},"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Unauthorized","content":{"application/json":{"example":{"success":false,"error":"Unauthorized","code":"UNAUTHORIZED","timestamp":"2026-08-19T09:41:12.004Z","requestId":"req_01J5X8ZC3K4T7Q9M2W6B0N1V4H"},"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"402":{"description":"Storage quota exhausted for the organization plan","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Forbidden — missing scope","content":{"application/json":{"example":{"success":false,"error":"Forbidden","code":"FORBIDDEN","timestamp":"2026-08-19T09:41:12.004Z","requestId":"req_01J5X8ZC3K4T7Q9M2W6B0N1V4H"},"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not found","content":{"application/json":{"example":{"success":false,"error":"Resource not found","code":"NOT_FOUND","timestamp":"2026-08-19T09:41:12.004Z","requestId":"req_01J5X8ZC3K4T7Q9M2W6B0N1V4H"},"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"411":{"description":"Content-Length is required for a raw (non-multipart) body","content":{"application/json":{"example":{"success":false,"error":"Content-Length is required for this upload","code":"LENGTH_REQUIRED","timestamp":"2026-08-19T09:41:12.004Z","requestId":"req_01J5X8ZC3K4T7Q9M2W6B0N1V4H"},"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"413":{"description":"Upload exceeds API_UPLOAD_MAX_BYTES (details.maxBytes)","content":{"application/json":{"example":{"success":false,"error":"Upload exceeds the maximum allowed size","code":"PAYLOAD_TOO_LARGE","details":{"maxBytes":262144000},"timestamp":"2026-08-19T09:41:12.004Z","requestId":"req_01J5X8ZC3K4T7Q9M2W6B0N1V4H"},"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"422":{"description":"Rejected file type, unverifiable content, or checksum mismatch","content":{"application/json":{"example":{"success":false,"error":"Validation failed","code":"VALIDATION_ERROR","timestamp":"2026-08-19T09:41:12.004Z","requestId":"req_01J5X8ZC3K4T7Q9M2W6B0N1V4H"},"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limit exceeded","content":{"application/json":{"example":{"success":false,"error":"Too many requests","code":"TOO_MANY_REQUESTS","timestamp":"2026-08-19T09:41:12.004Z","requestId":"req_01J5X8ZC3K4T7Q9M2W6B0N1V4H"},"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"503":{"description":"Object storage not configured","content":{"application/json":{"example":{"success":false,"error":"Service unavailable","code":"SERVICE_UNAVAILABLE","timestamp":"2026-08-19T09:41:12.004Z","requestId":"req_01J5X8ZC3K4T7Q9M2W6B0N1V4H"},"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/controls/{id}":{"get":{"operationId":"getControlsById","tags":["Controls"],"summary":"Get a control","description":"One control from the calling key's organization. A control in another organization is a 404, not a 403 — \"absent\" and \"not yours\" collapse to one answer so the endpoint is not an existence oracle over other tenants' ids.","security":[{"bearerAuth":["controls:read"]}],"parameters":[{"schema":{"type":"string","format":"uuid"},"required":true,"name":"id","in":"path"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","enum":[true]},"data":{"$ref":"#/components/schemas/Control"},"timestamp":{"type":"string","format":"date-time"},"requestId":{"type":"string"},"message":{"type":"string"}},"required":["success","data","timestamp"]},"example":{"success":true,"data":{"id":"748e2ee7-60d3-427f-8974-5934b2286690","organizationId":"4d97bae6-09db-44ec-8314-543d620095bb","displayId":"string","name":"string","description":"string","status":"string","domain":"string","ownerUserId":"92957f2d-f057-46fd-874b-91da49f6a07a","effectiveDate":"string","createdAt":"2026-08-19T09:41:12.004Z","updatedAt":"2026-08-19T09:41:12.004Z"},"timestamp":"2026-08-19T09:41:12.004Z","requestId":"req_01J5X8ZC3K4T7Q9M2W6B0N1V4H","message":"string"}}}},"400":{"description":"Validation error","content":{"application/json":{"example":{"success":false,"error":"Bad request","code":"BAD_REQUEST","timestamp":"2026-08-19T09:41:12.004Z","requestId":"req_01J5X8ZC3K4T7Q9M2W6B0N1V4H"},"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Unauthorized","content":{"application/json":{"example":{"success":false,"error":"Unauthorized","code":"UNAUTHORIZED","timestamp":"2026-08-19T09:41:12.004Z","requestId":"req_01J5X8ZC3K4T7Q9M2W6B0N1V4H"},"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Forbidden — missing scope","content":{"application/json":{"example":{"success":false,"error":"Forbidden","code":"FORBIDDEN","timestamp":"2026-08-19T09:41:12.004Z","requestId":"req_01J5X8ZC3K4T7Q9M2W6B0N1V4H"},"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not found","content":{"application/json":{"example":{"success":false,"error":"Resource not found","code":"NOT_FOUND","timestamp":"2026-08-19T09:41:12.004Z","requestId":"req_01J5X8ZC3K4T7Q9M2W6B0N1V4H"},"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limit exceeded","content":{"application/json":{"example":{"success":false,"error":"Too many requests","code":"TOO_MANY_REQUESTS","timestamp":"2026-08-19T09:41:12.004Z","requestId":"req_01J5X8ZC3K4T7Q9M2W6B0N1V4H"},"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/controls/{id}/mappings":{"get":{"operationId":"getControlsByIdMappings","tags":["Controls"],"summary":"List a control's framework mappings","description":"Which framework citations this control satisfies — the join that lets a caller answer \"what covers DORA Art. 5?\" from their own side. Each row names the framework by CODE as well as id, because the code is what every other surface and deep link carries while the id is a per-environment uuid. A control in another organization is a 404, never a 403.","security":[{"bearerAuth":["controls:read"]}],"parameters":[{"schema":{"type":"string","format":"uuid"},"required":true,"name":"id","in":"path"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","enum":[true]},"data":{"type":"array","items":{"$ref":"#/components/schemas/ControlFrameworkMapping"}},"timestamp":{"type":"string","format":"date-time"},"requestId":{"type":"string"},"message":{"type":"string"}},"required":["success","data","timestamp"]},"example":{"success":true,"data":[{"id":"2cd2fdb5-4725-4715-85e1-47a217a3ca52","controlId":"0689eba0-ed1d-4006-8b20-d7df1fb3cdc1","frameworkId":"4abef7fb-a3a0-4cfb-8d72-5a6817045804","frameworkCode":"string","frameworkName":"string","citationId":"d1fe2056-e70c-443c-884b-4f2d078d9d8b","citationArticleRef":"string","citationTitle":"string","mappingSource":"string","confirmedAt":"2026-08-19T09:41:12.004Z","createdAt":"2026-08-19T09:41:12.004Z"}],"timestamp":"2026-08-19T09:41:12.004Z","requestId":"req_01J5X8ZC3K4T7Q9M2W6B0N1V4H","message":"string"}}}},"400":{"description":"Validation error","content":{"application/json":{"example":{"success":false,"error":"Bad request","code":"BAD_REQUEST","timestamp":"2026-08-19T09:41:12.004Z","requestId":"req_01J5X8ZC3K4T7Q9M2W6B0N1V4H"},"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Unauthorized","content":{"application/json":{"example":{"success":false,"error":"Unauthorized","code":"UNAUTHORIZED","timestamp":"2026-08-19T09:41:12.004Z","requestId":"req_01J5X8ZC3K4T7Q9M2W6B0N1V4H"},"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Forbidden — missing scope","content":{"application/json":{"example":{"success":false,"error":"Forbidden","code":"FORBIDDEN","timestamp":"2026-08-19T09:41:12.004Z","requestId":"req_01J5X8ZC3K4T7Q9M2W6B0N1V4H"},"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not found","content":{"application/json":{"example":{"success":false,"error":"Resource not found","code":"NOT_FOUND","timestamp":"2026-08-19T09:41:12.004Z","requestId":"req_01J5X8ZC3K4T7Q9M2W6B0N1V4H"},"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limit exceeded","content":{"application/json":{"example":{"success":false,"error":"Too many requests","code":"TOO_MANY_REQUESTS","timestamp":"2026-08-19T09:41:12.004Z","requestId":"req_01J5X8ZC3K4T7Q9M2W6B0N1V4H"},"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/evidence":{"get":{"operationId":"getEvidence","tags":["Evidence"],"summary":"List evidence (cursor-paginated)","description":"Cursor-paginated read of the test_evidence feed. Pass `?cursor=<opaque>&limit=<n>` to advance; the response carries `cursor.nextCursor` (null on the last page) plus `cursor.hasMore`. The legacy `?page=` parameter returns 400.","security":[{"bearerAuth":["evidence:read"]}],"parameters":[{"schema":{"type":"string","minLength":1},"required":false,"name":"cursor","in":"query"},{"schema":{"type":"integer","minimum":1,"maximum":500,"default":50},"required":false,"name":"limit","in":"query"},{"schema":{"type":"string","format":"uuid"},"required":false,"name":"controlId","in":"query"},{"schema":{"type":"string","enum":["manual","attestation","automated","semi_auto"]},"required":false,"name":"testType","in":"query"},{"schema":{"type":"string","enum":["pass","fail","warn","error"]},"required":false,"name":"status","in":"query"},{"schema":{"anyOf":[{"type":"boolean"},{"type":"string","enum":["true","false"]}]},"required":false,"name":"isSensitive","in":"query"},{"schema":{"anyOf":[{"type":"boolean"},{"type":"string","enum":["true","false"]}]},"required":false,"name":"includeSuperseded","in":"query"},{"schema":{"type":"string","format":"date-time"},"required":false,"name":"collectedFrom","in":"query"},{"schema":{"type":"string","format":"date-time"},"required":false,"name":"collectedTo","in":"query"},{"schema":{"type":"string","format":"date-time"},"required":false,"name":"from","in":"query"},{"schema":{"type":"string","format":"date-time"},"required":false,"name":"to","in":"query"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","enum":[true]},"data":{"type":"array","items":{"$ref":"#/components/schemas/EvidenceItem"}},"timestamp":{"type":"string","format":"date-time"},"requestId":{"type":"string"},"message":{"type":"string"},"cursor":{"$ref":"#/components/schemas/CursorMeta"}},"required":["success","data","timestamp","cursor"]},"example":{"success":true,"data":[{"id":"336749c2-ab99-4940-8502-c479805b50c7","organizationId":"65cc03cb-0929-456b-850d-52b81ff93df4","controlId":"2af92ac9-713e-4d91-872d-4cd68e4fee96","controlDisplayId":"string","controlName":"string","testType":"string","source":"string","status":"string","summary":"string","isSensitive":true,"collectedAt":"2026-08-19T09:41:12.004Z","expiresAt":"2026-08-19T09:41:12.004Z","supersededBy":"1a80c892-48bb-4ab0-8286-e7c9575ee7b7"}],"timestamp":"2026-08-19T09:41:12.004Z","requestId":"req_01J5X8ZC3K4T7Q9M2W6B0N1V4H","message":"string","cursor":{"nextCursor":"string","hasMore":true,"limit":1}}}}},"400":{"description":"Validation error","content":{"application/json":{"example":{"success":false,"error":"Bad request","code":"BAD_REQUEST","timestamp":"2026-08-19T09:41:12.004Z","requestId":"req_01J5X8ZC3K4T7Q9M2W6B0N1V4H"},"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Unauthorized","content":{"application/json":{"example":{"success":false,"error":"Unauthorized","code":"UNAUTHORIZED","timestamp":"2026-08-19T09:41:12.004Z","requestId":"req_01J5X8ZC3K4T7Q9M2W6B0N1V4H"},"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Forbidden — missing scope","content":{"application/json":{"example":{"success":false,"error":"Forbidden","code":"FORBIDDEN","timestamp":"2026-08-19T09:41:12.004Z","requestId":"req_01J5X8ZC3K4T7Q9M2W6B0N1V4H"},"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not found","content":{"application/json":{"example":{"success":false,"error":"Resource not found","code":"NOT_FOUND","timestamp":"2026-08-19T09:41:12.004Z","requestId":"req_01J5X8ZC3K4T7Q9M2W6B0N1V4H"},"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limit exceeded","content":{"application/json":{"example":{"success":false,"error":"Too many requests","code":"TOO_MANY_REQUESTS","timestamp":"2026-08-19T09:41:12.004Z","requestId":"req_01J5X8ZC3K4T7Q9M2W6B0N1V4H"},"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/evidence/{id}":{"get":{"operationId":"getEvidenceById","tags":["Evidence"],"summary":"Get an evidence record","description":"Poll this after an upload to follow `file.scanStatus`. Sensitive rows come back with their descriptive fields redacted — an API key is not a named reader (see the download endpoint).","security":[{"bearerAuth":["evidence:read"]}],"parameters":[{"schema":{"type":"string","format":"uuid"},"required":true,"name":"id","in":"path"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","enum":[true]},"data":{"$ref":"#/components/schemas/EvidenceItem"},"timestamp":{"type":"string","format":"date-time"},"requestId":{"type":"string"},"message":{"type":"string"}},"required":["success","data","timestamp"]},"example":{"success":true,"data":{"id":"bf8196c2-3900-4040-8e7e-59791de6dfc7","organizationId":"d484c0cb-55fb-4c6b-82e4-d7b88a3f9cf4","controlId":"8d6ea9c9-7035-4a91-85e4-63d6a8892396","controlDisplayId":"string","controlName":"string","testType":"string","source":"string","status":"string","summary":"string","isSensitive":true,"collectedAt":"2026-08-19T09:41:12.004Z","expiresAt":"2026-08-19T09:41:12.004Z","supersededBy":"34b9fd92-90ca-49b0-813f-a4c9a4306eb7"},"timestamp":"2026-08-19T09:41:12.004Z","requestId":"req_01J5X8ZC3K4T7Q9M2W6B0N1V4H","message":"string"}}}},"400":{"description":"Validation error","content":{"application/json":{"example":{"success":false,"error":"Bad request","code":"BAD_REQUEST","timestamp":"2026-08-19T09:41:12.004Z","requestId":"req_01J5X8ZC3K4T7Q9M2W6B0N1V4H"},"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Unauthorized","content":{"application/json":{"example":{"success":false,"error":"Unauthorized","code":"UNAUTHORIZED","timestamp":"2026-08-19T09:41:12.004Z","requestId":"req_01J5X8ZC3K4T7Q9M2W6B0N1V4H"},"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Forbidden — missing scope","content":{"application/json":{"example":{"success":false,"error":"Forbidden","code":"FORBIDDEN","timestamp":"2026-08-19T09:41:12.004Z","requestId":"req_01J5X8ZC3K4T7Q9M2W6B0N1V4H"},"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not found","content":{"application/json":{"example":{"success":false,"error":"Resource not found","code":"NOT_FOUND","timestamp":"2026-08-19T09:41:12.004Z","requestId":"req_01J5X8ZC3K4T7Q9M2W6B0N1V4H"},"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limit exceeded","content":{"application/json":{"example":{"success":false,"error":"Too many requests","code":"TOO_MANY_REQUESTS","timestamp":"2026-08-19T09:41:12.004Z","requestId":"req_01J5X8ZC3K4T7Q9M2W6B0N1V4H"},"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/evidence/{id}/download":{"get":{"operationId":"getEvidenceByIdDownload","tags":["Evidence"],"summary":"Download an evidence document","description":"Streams the stored bytes. Responds `application/octet-stream` (or the stored content type) with `Content-Disposition: attachment`, NOT the JSON envelope. Evidence flagged sensitive is refused with 403 for an API key and the attempt is audited: sensitivity is gated on who is reading, and a key is nobody in particular.","security":[{"bearerAuth":["evidence:read"]}],"parameters":[{"schema":{"type":"string","format":"uuid"},"required":true,"name":"id","in":"path"}],"responses":{"200":{"description":"The document bytes","content":{"application/json":{"schema":{"type":"string","format":"binary"},"example":"<binary>"}}},"400":{"description":"Validation error","content":{"application/json":{"example":{"success":false,"error":"Bad request","code":"BAD_REQUEST","timestamp":"2026-08-19T09:41:12.004Z","requestId":"req_01J5X8ZC3K4T7Q9M2W6B0N1V4H"},"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Unauthorized","content":{"application/json":{"example":{"success":false,"error":"Unauthorized","code":"UNAUTHORIZED","timestamp":"2026-08-19T09:41:12.004Z","requestId":"req_01J5X8ZC3K4T7Q9M2W6B0N1V4H"},"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Sensitive evidence — not readable by an API key","content":{"application/json":{"example":{"success":false,"error":"Forbidden","code":"FORBIDDEN","timestamp":"2026-08-19T09:41:12.004Z","requestId":"req_01J5X8ZC3K4T7Q9M2W6B0N1V4H"},"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not found","content":{"application/json":{"example":{"success":false,"error":"Resource not found","code":"NOT_FOUND","timestamp":"2026-08-19T09:41:12.004Z","requestId":"req_01J5X8ZC3K4T7Q9M2W6B0N1V4H"},"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limit exceeded","content":{"application/json":{"example":{"success":false,"error":"Too many requests","code":"TOO_MANY_REQUESTS","timestamp":"2026-08-19T09:41:12.004Z","requestId":"req_01J5X8ZC3K4T7Q9M2W6B0N1V4H"},"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"503":{"description":"Object storage not configured","content":{"application/json":{"example":{"success":false,"error":"Service unavailable","code":"SERVICE_UNAVAILABLE","timestamp":"2026-08-19T09:41:12.004Z","requestId":"req_01J5X8ZC3K4T7Q9M2W6B0N1V4H"},"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/incidents":{"post":{"operationId":"postIncidents","tags":["Incidents"],"summary":"File an incident","description":"Creates an ICT incident in the calling key's organization. `reportedAt` is the moment the ENTITY BECAME AWARE of the incident, and every DORA Art. 19 deadline is computed from it — initial notification at `min(classifiedAt + 4h, reportedAt + 24h)`, intermediate at +72h, final at +1 month. Send it. Omitted, it defaults to the moment this row is written, so a relay that batches, a queue that backs up, or a replay of yesterday's alerts each move a supervisory deadline against a four-hour window. ISO 8601 with an offset; a value in the future is refused with 422.\n\nIdempotent on the optional `idempotencyKey`: a second submission carrying a key an earlier one used returns THAT incident with **200** and `Idempotent-Replay: true`, and files nothing — no duplicate row, no audit entry, no `incident.created` event. A first submission answers **201** with `Idempotent-Replay: false`. Omitting the key is legal and is never deduplicated.\n\nThe body is strict: an unrecognised field is a **422** naming it, never a silent no-op. `status` is refused by name — transitions are a state machine with their own endpoints.","security":[{"bearerAuth":["incidents:write"]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"title":{"type":"string","minLength":1,"maxLength":255},"description":{"type":"string"},"priority":{"type":"string","enum":["low","medium","high","critical"],"default":"medium"},"vendorId":{"anyOf":[{"type":"string","format":"uuid"},{"type":"string","enum":[""]}]},"assignedTo":{"anyOf":[{"type":"string","format":"uuid"},{"type":"string","enum":[""]}]},"dueDate":{"anyOf":[{"type":"string","format":"date"},{"type":"string","enum":[""]}]},"businessImpact":{"type":"string","enum":["None","Low","Medium","High","Critical"]},"affectedCustomers":{"anyOf":[{"type":"integer","minimum":0},{"type":"string","enum":[""]},{"type":"null"}]},"reportedAt":{"type":"string","format":"date-time"},"category":{"type":"string","minLength":1,"maxLength":50},"incidentType":{"type":"string","minLength":1,"maxLength":50},"affectedSystems":{"anyOf":[{"type":"string","maxLength":2000},{"type":"string","enum":[""]}]},"affectedServices":{"anyOf":[{"type":"string","maxLength":2000},{"type":"string","enum":[""]}]},"impactAssessment":{"anyOf":[{"type":"string","maxLength":5000},{"type":"string","enum":[""]}]},"escalationLevel":{"type":"integer","minimum":1,"maximum":5},"estimatedFinancialImpact":{"anyOf":[{"type":"number"},{"type":"string","pattern":"^\\d+(\\.\\d{1,2})?$"}]},"idempotencyKey":{"type":"string","minLength":8,"maxLength":64}},"required":["title"],"additionalProperties":false}}}},"responses":{"201":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","enum":[true]},"data":{"$ref":"#/components/schemas/Incident"},"timestamp":{"type":"string","format":"date-time"},"requestId":{"type":"string"},"message":{"type":"string"}},"required":["success","data","timestamp"]},"example":{"success":true,"data":{"id":"55d0e4df-f4d8-47e7-8479-2bece2c01e38","organizationId":"d5ad156e-cb78-4904-860b-460574bf3393","title":"string","description":"string","status":"string","priority":"string","category":"string","incidentType":"string","reportedAt":"2026-08-19T09:41:12.004Z","createdAt":"2026-08-19T09:41:12.004Z","updatedAt":"2026-08-19T09:41:12.004Z","resolvedAt":"2026-08-19T09:41:12.004Z","closedAt":"2026-08-19T09:41:12.004Z","dueDate":"string","vendorId":"9d3b4b61-e757-4cd9-8905-1b2e5d09c31e","assignedTo":"067ed2bb-f2a5-493b-82e2-932846adae44","reportedBy":"d80fa382-a09e-4280-8c55-143996eedc07","businessImpact":"string","affectedCustomers":1,"affectedSystems":"string","affectedServices":"string","impactAssessment":"string","escalationLevel":1,"estimatedFinancialImpact":"string","idempotencyKey":"string"},"timestamp":"2026-08-19T09:41:12.004Z","requestId":"req_01J5X8ZC3K4T7Q9M2W6B0N1V4H","message":"string"}}}},"400":{"description":"Validation error","content":{"application/json":{"example":{"success":false,"error":"Bad request","code":"BAD_REQUEST","timestamp":"2026-08-19T09:41:12.004Z","requestId":"req_01J5X8ZC3K4T7Q9M2W6B0N1V4H"},"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Unauthorized","content":{"application/json":{"example":{"success":false,"error":"Unauthorized","code":"UNAUTHORIZED","timestamp":"2026-08-19T09:41:12.004Z","requestId":"req_01J5X8ZC3K4T7Q9M2W6B0N1V4H"},"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Forbidden — missing scope","content":{"application/json":{"example":{"success":false,"error":"Forbidden","code":"FORBIDDEN","timestamp":"2026-08-19T09:41:12.004Z","requestId":"req_01J5X8ZC3K4T7Q9M2W6B0N1V4H"},"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not found","content":{"application/json":{"example":{"success":false,"error":"Resource not found","code":"NOT_FOUND","timestamp":"2026-08-19T09:41:12.004Z","requestId":"req_01J5X8ZC3K4T7Q9M2W6B0N1V4H"},"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"The API key has no resolvable owner, so the incident cannot name a user (`API_CLIENT_OWNER_UNRESOLVED`). Re-issue the key with an owner.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"422":{"description":"Unrecognised or invalid field — the response names it","content":{"application/json":{"example":{"success":false,"error":"Validation failed","code":"VALIDATION_ERROR","timestamp":"2026-08-19T09:41:12.004Z","requestId":"req_01J5X8ZC3K4T7Q9M2W6B0N1V4H"},"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limit exceeded","content":{"application/json":{"example":{"success":false,"error":"Too many requests","code":"TOO_MANY_REQUESTS","timestamp":"2026-08-19T09:41:12.004Z","requestId":"req_01J5X8ZC3K4T7Q9M2W6B0N1V4H"},"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}},"get":{"operationId":"getIncidents","tags":["Incidents"],"summary":"List incidents (cursor-paginated)","description":"Cursor-paginated read of the incident register. Pass `?cursor=<opaque>&limit=<n>` to advance; the response carries `cursor.nextCursor` (null on the last page) plus `cursor.hasMore`. The legacy `?page=` parameter returns 400. Ordering is newest-first by creation time — NOT by `reportedAt`, which a caller supplies and which a backfilled alert can therefore place anywhere in the sequence. Filter on `reportedFrom` / `reportedTo` to ask about awareness time.","security":[{"bearerAuth":["incidents:read"]}],"parameters":[{"schema":{"type":"string","minLength":1},"required":false,"name":"cursor","in":"query"},{"schema":{"type":"integer","minimum":1,"maximum":500,"default":50},"required":false,"name":"limit","in":"query"},{"schema":{"type":"string","enum":["open","in_progress","resolved","closed"]},"required":false,"name":"status","in":"query"},{"schema":{"type":"string","enum":["low","medium","high","critical"]},"required":false,"name":"priority","in":"query"},{"schema":{"type":"string","format":"uuid"},"required":false,"name":"vendorId","in":"query"},{"schema":{"type":"string","format":"date-time"},"required":false,"name":"reportedFrom","in":"query"},{"schema":{"type":"string","format":"date-time"},"required":false,"name":"reportedTo","in":"query"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","enum":[true]},"data":{"type":"array","items":{"$ref":"#/components/schemas/Incident"}},"timestamp":{"type":"string","format":"date-time"},"requestId":{"type":"string"},"message":{"type":"string"},"cursor":{"$ref":"#/components/schemas/CursorMeta"}},"required":["success","data","timestamp","cursor"]},"example":{"success":true,"data":[{"id":"4efa7204-5a41-4f72-861b-9ee3047b25a5","organizationId":"31311b39-ab4d-4de1-8d94-4ac6a271af66","title":"string","description":"string","status":"string","priority":"string","category":"string","incidentType":"string","reportedAt":"2026-08-19T09:41:12.004Z","createdAt":"2026-08-19T09:41:12.004Z","updatedAt":"2026-08-19T09:41:12.004Z","resolvedAt":"2026-08-19T09:41:12.004Z","closedAt":"2026-08-19T09:41:12.004Z","dueDate":"string","vendorId":"d0858aae-ee39-4cc4-8b33-dd4523a54d53","assignedTo":"a87c5ad0-0dc2-4896-8eed-528f9a98f0d1","reportedBy":"038b4065-fb36-4225-8c9c-81d2606063e2","businessImpact":"string","affectedCustomers":1,"affectedSystems":"string","affectedServices":"string","impactAssessment":"string","escalationLevel":1,"estimatedFinancialImpact":"string","idempotencyKey":"string"}],"timestamp":"2026-08-19T09:41:12.004Z","requestId":"req_01J5X8ZC3K4T7Q9M2W6B0N1V4H","message":"string","cursor":{"nextCursor":"string","hasMore":true,"limit":1}}}}},"400":{"description":"Validation error","content":{"application/json":{"example":{"success":false,"error":"Bad request","code":"BAD_REQUEST","timestamp":"2026-08-19T09:41:12.004Z","requestId":"req_01J5X8ZC3K4T7Q9M2W6B0N1V4H"},"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Unauthorized","content":{"application/json":{"example":{"success":false,"error":"Unauthorized","code":"UNAUTHORIZED","timestamp":"2026-08-19T09:41:12.004Z","requestId":"req_01J5X8ZC3K4T7Q9M2W6B0N1V4H"},"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Forbidden — missing scope","content":{"application/json":{"example":{"success":false,"error":"Forbidden","code":"FORBIDDEN","timestamp":"2026-08-19T09:41:12.004Z","requestId":"req_01J5X8ZC3K4T7Q9M2W6B0N1V4H"},"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not found","content":{"application/json":{"example":{"success":false,"error":"Resource not found","code":"NOT_FOUND","timestamp":"2026-08-19T09:41:12.004Z","requestId":"req_01J5X8ZC3K4T7Q9M2W6B0N1V4H"},"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limit exceeded","content":{"application/json":{"example":{"success":false,"error":"Too many requests","code":"TOO_MANY_REQUESTS","timestamp":"2026-08-19T09:41:12.004Z","requestId":"req_01J5X8ZC3K4T7Q9M2W6B0N1V4H"},"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/incidents/{id}":{"get":{"operationId":"getIncidentsById","tags":["Incidents"],"summary":"Get an incident","description":"Returns one incident from the calling key's organization, plus a `reportedByUser` object naming the person the record is attributed to — for an incident filed over this API that is the key's owner. An incident in another organization is a 404, not a 403.","security":[{"bearerAuth":["incidents:read"]}],"parameters":[{"schema":{"type":"string","format":"uuid"},"required":true,"name":"id","in":"path"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","enum":[true]},"data":{"$ref":"#/components/schemas/Incident"},"timestamp":{"type":"string","format":"date-time"},"requestId":{"type":"string"},"message":{"type":"string"}},"required":["success","data","timestamp"]},"example":{"success":true,"data":{"id":"98d8e0c4-6369-47b2-809e-8ba33095d7e5","organizationId":"bab416f9-e480-4d21-87c7-0c863058b0a6","title":"string","description":"string","status":"string","priority":"string","category":"string","incidentType":"string","reportedAt":"2026-08-19T09:41:12.004Z","createdAt":"2026-08-19T09:41:12.004Z","updatedAt":"2026-08-19T09:41:12.004Z","resolvedAt":"2026-08-19T09:41:12.004Z","closedAt":"2026-08-19T09:41:12.004Z","dueDate":"string","vendorId":"be48376e-f7af-4f04-8fe0-38059ef82993","assignedTo":"850b0790-025c-4ad6-8d45-ad4fafafcd11","reportedBy":"af301e25-efbf-4765-8068-f592ab3a9b22","businessImpact":"string","affectedCustomers":1,"affectedSystems":"string","affectedServices":"string","impactAssessment":"string","escalationLevel":1,"estimatedFinancialImpact":"string","idempotencyKey":"string"},"timestamp":"2026-08-19T09:41:12.004Z","requestId":"req_01J5X8ZC3K4T7Q9M2W6B0N1V4H","message":"string"}}}},"400":{"description":"Validation error","content":{"application/json":{"example":{"success":false,"error":"Bad request","code":"BAD_REQUEST","timestamp":"2026-08-19T09:41:12.004Z","requestId":"req_01J5X8ZC3K4T7Q9M2W6B0N1V4H"},"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Unauthorized","content":{"application/json":{"example":{"success":false,"error":"Unauthorized","code":"UNAUTHORIZED","timestamp":"2026-08-19T09:41:12.004Z","requestId":"req_01J5X8ZC3K4T7Q9M2W6B0N1V4H"},"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Forbidden — missing scope","content":{"application/json":{"example":{"success":false,"error":"Forbidden","code":"FORBIDDEN","timestamp":"2026-08-19T09:41:12.004Z","requestId":"req_01J5X8ZC3K4T7Q9M2W6B0N1V4H"},"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not found","content":{"application/json":{"example":{"success":false,"error":"Resource not found","code":"NOT_FOUND","timestamp":"2026-08-19T09:41:12.004Z","requestId":"req_01J5X8ZC3K4T7Q9M2W6B0N1V4H"},"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limit exceeded","content":{"application/json":{"example":{"success":false,"error":"Too many requests","code":"TOO_MANY_REQUESTS","timestamp":"2026-08-19T09:41:12.004Z","requestId":"req_01J5X8ZC3K4T7Q9M2W6B0N1V4H"},"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/iq-extension/log-fill":{"post":{"operationId":"postIqExtensionLogFill","tags":["OQ Extension"],"summary":"Audit a portal fill — never mutates the draft row","security":[{"bearerAuth":["inbound-questionnaire:write"]}],"requestBody":{"description":"draftId + portalUrl + optional fieldHint","required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"draftId":{"type":"string","format":"uuid"},"portalUrl":{"type":"string","maxLength":2048,"format":"uri"},"fieldHint":{"type":["string","null"],"maxLength":256}},"required":["draftId","portalUrl"]}}}},"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","enum":[true]},"data":{"$ref":"#/components/schemas/IqExtensionLogFillResult"},"timestamp":{"type":"string","format":"date-time"},"requestId":{"type":"string"},"message":{"type":"string"}},"required":["success","data","timestamp"]},"example":{"success":true,"data":{"ok":true},"timestamp":"2026-08-19T09:41:12.004Z","requestId":"req_01J5X8ZC3K4T7Q9M2W6B0N1V4H","message":"string"}}}},"400":{"description":"Validation error","content":{"application/json":{"example":{"success":false,"error":"Bad request","code":"BAD_REQUEST","timestamp":"2026-08-19T09:41:12.004Z","requestId":"req_01J5X8ZC3K4T7Q9M2W6B0N1V4H"},"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Unauthorized","content":{"application/json":{"example":{"success":false,"error":"Unauthorized","code":"UNAUTHORIZED","timestamp":"2026-08-19T09:41:12.004Z","requestId":"req_01J5X8ZC3K4T7Q9M2W6B0N1V4H"},"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Forbidden — missing scope","content":{"application/json":{"example":{"success":false,"error":"Forbidden","code":"FORBIDDEN","timestamp":"2026-08-19T09:41:12.004Z","requestId":"req_01J5X8ZC3K4T7Q9M2W6B0N1V4H"},"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not found","content":{"application/json":{"example":{"success":false,"error":"Resource not found","code":"NOT_FOUND","timestamp":"2026-08-19T09:41:12.004Z","requestId":"req_01J5X8ZC3K4T7Q9M2W6B0N1V4H"},"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limit exceeded","content":{"application/json":{"example":{"success":false,"error":"Too many requests","code":"TOO_MANY_REQUESTS","timestamp":"2026-08-19T09:41:12.004Z","requestId":"req_01J5X8ZC3K4T7Q9M2W6B0N1V4H"},"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/iq-extension/match":{"post":{"operationId":"postIqExtensionMatch","tags":["OQ Extension"],"summary":"Match a portal-page snippet to the best (question, draft) pair in the active import","security":[{"bearerAuth":["inbound-questionnaire:read"]}],"requestBody":{"description":"Active import id + portal-page text snippet","required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"activeImportId":{"type":"string","format":"uuid"},"contextText":{"type":"string","minLength":1,"maxLength":4000}},"required":["activeImportId","contextText"]}}}},"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","enum":[true]},"data":{"$ref":"#/components/schemas/IqExtensionMatchResult"},"timestamp":{"type":"string","format":"date-time"},"requestId":{"type":"string"},"message":{"type":"string"}},"required":["success","data","timestamp"]},"example":{"success":true,"data":{"question":{"id":"9309eac7-3d9c-441f-897d-281430061130","importId":"91d91934-cec2-4002-8d7b-11931fbcb0b5","ordinal":1,"questionText":"string","sourceSection":"string"},"draft":{"id":"88e69f36-b70c-4edc-87de-190d6ba1692b","questionId":"feed2416-634f-4b7c-859d-58ed2fb2f6cb","status":"string","draftAnswer":"string","editedAnswer":"string"},"score":0},"timestamp":"2026-08-19T09:41:12.004Z","requestId":"req_01J5X8ZC3K4T7Q9M2W6B0N1V4H","message":"string"}}}},"400":{"description":"Validation error","content":{"application/json":{"example":{"success":false,"error":"Bad request","code":"BAD_REQUEST","timestamp":"2026-08-19T09:41:12.004Z","requestId":"req_01J5X8ZC3K4T7Q9M2W6B0N1V4H"},"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Unauthorized","content":{"application/json":{"example":{"success":false,"error":"Unauthorized","code":"UNAUTHORIZED","timestamp":"2026-08-19T09:41:12.004Z","requestId":"req_01J5X8ZC3K4T7Q9M2W6B0N1V4H"},"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Forbidden — missing scope","content":{"application/json":{"example":{"success":false,"error":"Forbidden","code":"FORBIDDEN","timestamp":"2026-08-19T09:41:12.004Z","requestId":"req_01J5X8ZC3K4T7Q9M2W6B0N1V4H"},"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not found","content":{"application/json":{"example":{"success":false,"error":"Resource not found","code":"NOT_FOUND","timestamp":"2026-08-19T09:41:12.004Z","requestId":"req_01J5X8ZC3K4T7Q9M2W6B0N1V4H"},"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limit exceeded","content":{"application/json":{"example":{"success":false,"error":"Too many requests","code":"TOO_MANY_REQUESTS","timestamp":"2026-08-19T09:41:12.004Z","requestId":"req_01J5X8ZC3K4T7Q9M2W6B0N1V4H"},"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/policies":{"get":{"operationId":"getPolicies","tags":["Policies"],"summary":"List policies","description":"The organization's policy register, offset-paginated. Filter by `category`, `ownerUserId`, `lifecycleStatus` (`draft` | `published` | `archived`) or `businessUnitId`. Without `lifecycleStatus`, ARCHIVED policies are excluded — archived rows stay on the acknowledgement ledger but are not part of the live register, and a caller asking \"what are our policies\" means the live ones. Ask for them explicitly with `?lifecycleStatus=archived`. The query is strict: an unrecognised parameter is a 422 naming it, never a silently unfiltered 200.","security":[{"bearerAuth":["policies:read"]}],"parameters":[{"schema":{"type":"integer","minimum":1,"maximum":10000,"default":1},"required":false,"name":"page","in":"query"},{"schema":{"type":"integer","minimum":1,"maximum":500,"default":100},"required":false,"name":"limit","in":"query"},{"schema":{"type":"string"},"required":false,"name":"sortBy","in":"query"},{"schema":{"type":"string","enum":["asc","desc"],"default":"desc"},"required":false,"name":"sortOrder","in":"query"},{"schema":{"type":"string","minLength":1,"maxLength":100},"required":false,"name":"category","in":"query"},{"schema":{"type":"string","format":"uuid"},"required":false,"name":"ownerUserId","in":"query"},{"schema":{"type":"string","enum":["draft","published","archived"]},"required":false,"name":"lifecycleStatus","in":"query"},{"schema":{"type":"string","minLength":1,"maxLength":255},"required":false,"name":"search","in":"query"},{"schema":{"type":"string","format":"uuid"},"required":false,"name":"businessUnitId","in":"query"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","enum":[true]},"data":{"type":"array","items":{"$ref":"#/components/schemas/Policy"}},"timestamp":{"type":"string","format":"date-time"},"requestId":{"type":"string"},"message":{"type":"string"},"pagination":{"$ref":"#/components/schemas/Pagination"}},"required":["success","data","timestamp"]},"example":{"success":true,"data":[{"id":"483c5d95-4e07-44b5-8b8a-5a8230cc80f2","organizationId":"ddc1eef0-0a4b-46f6-894e-53afb14db631","slug":"string","displayName":"string","category":"string","ownerUserId":"32dc603f-4deb-4007-8dba-864cc4a16358","currentVersionId":"922807ac-c304-46ea-8870-10cbb76a75dd","lifecycleStatus":"string","renewalIntervalDays":1,"nextRenewalAt":"2026-08-19T09:41:12.004Z","businessUnitIds":["1e1a030a-6af2-4598-872d-130120f4f0df"],"createdAt":"2026-08-19T09:41:12.004Z","updatedAt":"2026-08-19T09:41:12.004Z"}],"timestamp":"2026-08-19T09:41:12.004Z","requestId":"req_01J5X8ZC3K4T7Q9M2W6B0N1V4H","message":"string","pagination":{"page":1,"limit":1,"total":1,"totalPages":1}}}}},"400":{"description":"Validation error","content":{"application/json":{"example":{"success":false,"error":"Bad request","code":"BAD_REQUEST","timestamp":"2026-08-19T09:41:12.004Z","requestId":"req_01J5X8ZC3K4T7Q9M2W6B0N1V4H"},"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Unauthorized","content":{"application/json":{"example":{"success":false,"error":"Unauthorized","code":"UNAUTHORIZED","timestamp":"2026-08-19T09:41:12.004Z","requestId":"req_01J5X8ZC3K4T7Q9M2W6B0N1V4H"},"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Forbidden — missing scope","content":{"application/json":{"example":{"success":false,"error":"Forbidden","code":"FORBIDDEN","timestamp":"2026-08-19T09:41:12.004Z","requestId":"req_01J5X8ZC3K4T7Q9M2W6B0N1V4H"},"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not found","content":{"application/json":{"example":{"success":false,"error":"Resource not found","code":"NOT_FOUND","timestamp":"2026-08-19T09:41:12.004Z","requestId":"req_01J5X8ZC3K4T7Q9M2W6B0N1V4H"},"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limit exceeded","content":{"application/json":{"example":{"success":false,"error":"Too many requests","code":"TOO_MANY_REQUESTS","timestamp":"2026-08-19T09:41:12.004Z","requestId":"req_01J5X8ZC3K4T7Q9M2W6B0N1V4H"},"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/policies/{id}":{"get":{"operationId":"getPoliciesById","tags":["Policies"],"summary":"Get a policy","description":"One policy from the calling key's organization. A policy in another organization is a 404, never a 403.","security":[{"bearerAuth":["policies:read"]}],"parameters":[{"schema":{"type":"string","format":"uuid"},"required":true,"name":"id","in":"path"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","enum":[true]},"data":{"$ref":"#/components/schemas/Policy"},"timestamp":{"type":"string","format":"date-time"},"requestId":{"type":"string"},"message":{"type":"string"}},"required":["success","data","timestamp"]},"example":{"success":true,"data":{"id":"cfc1722b-3686-468b-8e11-5818314db414","organizationId":"e391ec5a-96b7-4e88-8d2b-e4d1d1193b4f","slug":"string","displayName":"string","category":"string","ownerUserId":"6528e489-ca5f-46d1-86c5-fc965bac99d6","currentVersionId":"3a064f26-7bee-45ac-8795-a27da98ec47b","lifecycleStatus":"string","renewalIntervalDays":1,"nextRenewalAt":"2026-08-19T09:41:12.004Z","businessUnitIds":["48f1fcf4-caf1-4742-8ab9-fb5349c6a9f5"],"createdAt":"2026-08-19T09:41:12.004Z","updatedAt":"2026-08-19T09:41:12.004Z"},"timestamp":"2026-08-19T09:41:12.004Z","requestId":"req_01J5X8ZC3K4T7Q9M2W6B0N1V4H","message":"string"}}}},"400":{"description":"Validation error","content":{"application/json":{"example":{"success":false,"error":"Bad request","code":"BAD_REQUEST","timestamp":"2026-08-19T09:41:12.004Z","requestId":"req_01J5X8ZC3K4T7Q9M2W6B0N1V4H"},"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Unauthorized","content":{"application/json":{"example":{"success":false,"error":"Unauthorized","code":"UNAUTHORIZED","timestamp":"2026-08-19T09:41:12.004Z","requestId":"req_01J5X8ZC3K4T7Q9M2W6B0N1V4H"},"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Forbidden — missing scope","content":{"application/json":{"example":{"success":false,"error":"Forbidden","code":"FORBIDDEN","timestamp":"2026-08-19T09:41:12.004Z","requestId":"req_01J5X8ZC3K4T7Q9M2W6B0N1V4H"},"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not found","content":{"application/json":{"example":{"success":false,"error":"Resource not found","code":"NOT_FOUND","timestamp":"2026-08-19T09:41:12.004Z","requestId":"req_01J5X8ZC3K4T7Q9M2W6B0N1V4H"},"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limit exceeded","content":{"application/json":{"example":{"success":false,"error":"Too many requests","code":"TOO_MANY_REQUESTS","timestamp":"2026-08-19T09:41:12.004Z","requestId":"req_01J5X8ZC3K4T7Q9M2W6B0N1V4H"},"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/policies/{id}/versions":{"get":{"operationId":"getPoliciesByIdVersions","tags":["Policies"],"summary":"List a policy's versions","description":"Every version of one policy, with its approval status, locale and publication timestamp — the audit trail a reviewer asks for when the question is \"since when has this said that\". The document BODY is not included in the list; fetch a single version for it.","security":[{"bearerAuth":["policies:read"]}],"parameters":[{"schema":{"type":"string","format":"uuid"},"required":true,"name":"id","in":"path"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","enum":[true]},"data":{"type":"array","items":{"$ref":"#/components/schemas/PolicyVersion"}},"timestamp":{"type":"string","format":"date-time"},"requestId":{"type":"string"},"message":{"type":"string"}},"required":["success","data","timestamp"]},"example":{"success":true,"data":[{"id":"a9fc53f7-8d38-4aaf-8b6b-2cc489b77240","policyId":"11bf697d-6f53-42ed-8dc6-ccaabdf435ea","versionNumber":1,"locale":"string","title":"string","approvalStatus":"string","publishedAt":"2026-08-19T09:41:12.004Z","createdAt":"2026-08-19T09:41:12.004Z","updatedAt":"2026-08-19T09:41:12.004Z"}],"timestamp":"2026-08-19T09:41:12.004Z","requestId":"req_01J5X8ZC3K4T7Q9M2W6B0N1V4H","message":"string"}}}},"400":{"description":"Validation error","content":{"application/json":{"example":{"success":false,"error":"Bad request","code":"BAD_REQUEST","timestamp":"2026-08-19T09:41:12.004Z","requestId":"req_01J5X8ZC3K4T7Q9M2W6B0N1V4H"},"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Unauthorized","content":{"application/json":{"example":{"success":false,"error":"Unauthorized","code":"UNAUTHORIZED","timestamp":"2026-08-19T09:41:12.004Z","requestId":"req_01J5X8ZC3K4T7Q9M2W6B0N1V4H"},"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Forbidden — missing scope","content":{"application/json":{"example":{"success":false,"error":"Forbidden","code":"FORBIDDEN","timestamp":"2026-08-19T09:41:12.004Z","requestId":"req_01J5X8ZC3K4T7Q9M2W6B0N1V4H"},"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not found","content":{"application/json":{"example":{"success":false,"error":"Resource not found","code":"NOT_FOUND","timestamp":"2026-08-19T09:41:12.004Z","requestId":"req_01J5X8ZC3K4T7Q9M2W6B0N1V4H"},"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limit exceeded","content":{"application/json":{"example":{"success":false,"error":"Too many requests","code":"TOO_MANY_REQUESTS","timestamp":"2026-08-19T09:41:12.004Z","requestId":"req_01J5X8ZC3K4T7Q9M2W6B0N1V4H"},"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/policies/{id}/versions/{versionId}":{"get":{"operationId":"getPoliciesByIdVersionsByVersionId","tags":["Policies"],"summary":"Get a policy version","description":"One version, including `bodyRichtext` — the document itself, as a TipTap JSON node tree rather than HTML or Markdown. That is the stored form, and it is published as-is rather than rendered here: a server-side rendering would be a second answer to what the policy says, and the one a reader compares against the app would be whichever they happened to fetch.","security":[{"bearerAuth":["policies:read"]}],"parameters":[{"schema":{"type":"string","format":"uuid"},"required":true,"name":"id","in":"path"},{"schema":{"type":"string","format":"uuid"},"required":true,"name":"versionId","in":"path"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","enum":[true]},"data":{"$ref":"#/components/schemas/PolicyVersion"},"timestamp":{"type":"string","format":"date-time"},"requestId":{"type":"string"},"message":{"type":"string"}},"required":["success","data","timestamp"]},"example":{"success":true,"data":{"id":"03bdc489-6ebc-46d1-8495-dc9629ea39d6","policyId":"a180a5ff-3a85-4d47-83d8-a20c36071298","versionNumber":1,"locale":"string","title":"string","approvalStatus":"string","publishedAt":"2026-08-19T09:41:12.004Z","createdAt":"2026-08-19T09:41:12.004Z","updatedAt":"2026-08-19T09:41:12.004Z"},"timestamp":"2026-08-19T09:41:12.004Z","requestId":"req_01J5X8ZC3K4T7Q9M2W6B0N1V4H","message":"string"}}}},"400":{"description":"Validation error","content":{"application/json":{"example":{"success":false,"error":"Bad request","code":"BAD_REQUEST","timestamp":"2026-08-19T09:41:12.004Z","requestId":"req_01J5X8ZC3K4T7Q9M2W6B0N1V4H"},"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Unauthorized","content":{"application/json":{"example":{"success":false,"error":"Unauthorized","code":"UNAUTHORIZED","timestamp":"2026-08-19T09:41:12.004Z","requestId":"req_01J5X8ZC3K4T7Q9M2W6B0N1V4H"},"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Forbidden — missing scope","content":{"application/json":{"example":{"success":false,"error":"Forbidden","code":"FORBIDDEN","timestamp":"2026-08-19T09:41:12.004Z","requestId":"req_01J5X8ZC3K4T7Q9M2W6B0N1V4H"},"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not found","content":{"application/json":{"example":{"success":false,"error":"Resource not found","code":"NOT_FOUND","timestamp":"2026-08-19T09:41:12.004Z","requestId":"req_01J5X8ZC3K4T7Q9M2W6B0N1V4H"},"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limit exceeded","content":{"application/json":{"example":{"success":false,"error":"Too many requests","code":"TOO_MANY_REQUESTS","timestamp":"2026-08-19T09:41:12.004Z","requestId":"req_01J5X8ZC3K4T7Q9M2W6B0N1V4H"},"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/risk-registers":{"get":{"operationId":"getRiskRegisters","tags":["Risks"],"summary":"List risk registers","security":[{"bearerAuth":["risks:read"]}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","enum":[true]},"data":{"type":"array","items":{"$ref":"#/components/schemas/RiskRegister"}},"timestamp":{"type":"string","format":"date-time"},"requestId":{"type":"string"},"message":{"type":"string"},"pagination":{"$ref":"#/components/schemas/Pagination"}},"required":["success","data","timestamp"]},"example":{"success":true,"data":[{"id":"0d7ca467-a036-4aff-8241-8ab4cd2d5310","organizationId":"a8a43866-de84-456c-8a02-cdbd8b69da3b","name":"string","description":"string","isDefault":true,"scenarioSeq":1,"likelihoodScale":[{"score":1,"label":"string","description":"string"}],"impactScale":[{"score":1,"label":"string","description":"string"}],"createdBy":"270b45d9-51be-47c1-81a0-066640ea0c46","createdAt":"2026-08-19T09:41:12.004Z","updatedAt":"2026-08-19T09:41:12.004Z"}],"timestamp":"2026-08-19T09:41:12.004Z","requestId":"req_01J5X8ZC3K4T7Q9M2W6B0N1V4H","message":"string","pagination":{"page":1,"limit":1,"total":1,"totalPages":1}}}}},"400":{"description":"Validation error","content":{"application/json":{"example":{"success":false,"error":"Bad request","code":"BAD_REQUEST","timestamp":"2026-08-19T09:41:12.004Z","requestId":"req_01J5X8ZC3K4T7Q9M2W6B0N1V4H"},"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Unauthorized","content":{"application/json":{"example":{"success":false,"error":"Unauthorized","code":"UNAUTHORIZED","timestamp":"2026-08-19T09:41:12.004Z","requestId":"req_01J5X8ZC3K4T7Q9M2W6B0N1V4H"},"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Forbidden — missing scope","content":{"application/json":{"example":{"success":false,"error":"Forbidden","code":"FORBIDDEN","timestamp":"2026-08-19T09:41:12.004Z","requestId":"req_01J5X8ZC3K4T7Q9M2W6B0N1V4H"},"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not found","content":{"application/json":{"example":{"success":false,"error":"Resource not found","code":"NOT_FOUND","timestamp":"2026-08-19T09:41:12.004Z","requestId":"req_01J5X8ZC3K4T7Q9M2W6B0N1V4H"},"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limit exceeded","content":{"application/json":{"example":{"success":false,"error":"Too many requests","code":"TOO_MANY_REQUESTS","timestamp":"2026-08-19T09:41:12.004Z","requestId":"req_01J5X8ZC3K4T7Q9M2W6B0N1V4H"},"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/risk-registers/{id}":{"get":{"operationId":"getRiskRegistersById","tags":["Risks"],"summary":"Get a risk register by id","security":[{"bearerAuth":["risks:read"]}],"parameters":[{"schema":{"type":"string","format":"uuid"},"required":true,"name":"id","in":"path"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","enum":[true]},"data":{"$ref":"#/components/schemas/RiskRegister"},"timestamp":{"type":"string","format":"date-time"},"requestId":{"type":"string"},"message":{"type":"string"}},"required":["success","data","timestamp"]},"example":{"success":true,"data":{"id":"39e11e65-8462-4c25-8da0-8fd2c9c26de2","organizationId":"01d10ca0-7e16-4306-8307-60df1f9d78c1","name":"string","description":"string","isDefault":true,"scenarioSeq":1,"likelihoodScale":[{"score":1,"label":"string","description":"string"}],"impactScale":[{"score":1,"label":"string","description":"string"}],"createdBy":"cb491e57-591a-4fcf-811b-ee240ef7dc60","createdAt":"2026-08-19T09:41:12.004Z","updatedAt":"2026-08-19T09:41:12.004Z"},"timestamp":"2026-08-19T09:41:12.004Z","requestId":"req_01J5X8ZC3K4T7Q9M2W6B0N1V4H","message":"string"}}}},"400":{"description":"Validation error","content":{"application/json":{"example":{"success":false,"error":"Bad request","code":"BAD_REQUEST","timestamp":"2026-08-19T09:41:12.004Z","requestId":"req_01J5X8ZC3K4T7Q9M2W6B0N1V4H"},"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Unauthorized","content":{"application/json":{"example":{"success":false,"error":"Unauthorized","code":"UNAUTHORIZED","timestamp":"2026-08-19T09:41:12.004Z","requestId":"req_01J5X8ZC3K4T7Q9M2W6B0N1V4H"},"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Forbidden — missing scope","content":{"application/json":{"example":{"success":false,"error":"Forbidden","code":"FORBIDDEN","timestamp":"2026-08-19T09:41:12.004Z","requestId":"req_01J5X8ZC3K4T7Q9M2W6B0N1V4H"},"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not found","content":{"application/json":{"example":{"success":false,"error":"Resource not found","code":"NOT_FOUND","timestamp":"2026-08-19T09:41:12.004Z","requestId":"req_01J5X8ZC3K4T7Q9M2W6B0N1V4H"},"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limit exceeded","content":{"application/json":{"example":{"success":false,"error":"Too many requests","code":"TOO_MANY_REQUESTS","timestamp":"2026-08-19T09:41:12.004Z","requestId":"req_01J5X8ZC3K4T7Q9M2W6B0N1V4H"},"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/risk-scenarios":{"get":{"operationId":"getRiskScenarios","tags":["Risks"],"summary":"List risk scenarios","security":[{"bearerAuth":["risks:read"]}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","enum":[true]},"data":{"type":"array","items":{"$ref":"#/components/schemas/RiskScenario"}},"timestamp":{"type":"string","format":"date-time"},"requestId":{"type":"string"},"message":{"type":"string"},"pagination":{"$ref":"#/components/schemas/Pagination"}},"required":["success","data","timestamp"]},"example":{"success":true,"data":[{"id":"0461f0ce-b22e-4124-8585-0065f15f98b3","organizationId":"5c7ee077-10bb-482f-82eb-cd4459341bc0","registerId":"829b8b39-d5dc-4de1-8b9c-3ac688f07f66","displayId":"string","title":"string","description":"string","categoryId":"7f1a6b66-7a97-4e6c-8acb-b8bdd7b3cb3b","riskType":["confidentiality"],"inherentLikelihood":1,"inherentImpact":1,"residualLikelihood":1,"residualImpact":1,"lifecycleStatus":"open","approvalStatus":"draft","isArchived":true,"treatment":"mitigate","treatmentPlan":"string","ownerUserId":"2aa5f20e-2f3c-48e4-8282-03a553abb673","targetResolutionDate":"string","vendorId":"4e4fe7a8-f1c9-409e-8d81-0727f51e3c19","businessFunctionId":"3b151b60-643a-4b46-8c78-ed9f3d5e0b01","controlId":"944efe45-bf5a-49c5-8122-22b27ebca482","sourceTemplateId":"1f1ace07-fc32-41df-8f36-dd54b35e64f0","businessUnitIds":["5f7c048b-d93b-43ab-8019-2178838fb634"],"createdBy":"df9d971e-2114-4114-8ade-5735ad034223","createdAt":"2026-08-19T09:41:12.004Z","updatedAt":"2026-08-19T09:41:12.004Z","inherentScore":1,"residualScore":1}],"timestamp":"2026-08-19T09:41:12.004Z","requestId":"req_01J5X8ZC3K4T7Q9M2W6B0N1V4H","message":"string","pagination":{"page":1,"limit":1,"total":1,"totalPages":1}}}}},"400":{"description":"Validation error","content":{"application/json":{"example":{"success":false,"error":"Bad request","code":"BAD_REQUEST","timestamp":"2026-08-19T09:41:12.004Z","requestId":"req_01J5X8ZC3K4T7Q9M2W6B0N1V4H"},"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Unauthorized","content":{"application/json":{"example":{"success":false,"error":"Unauthorized","code":"UNAUTHORIZED","timestamp":"2026-08-19T09:41:12.004Z","requestId":"req_01J5X8ZC3K4T7Q9M2W6B0N1V4H"},"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Forbidden — missing scope","content":{"application/json":{"example":{"success":false,"error":"Forbidden","code":"FORBIDDEN","timestamp":"2026-08-19T09:41:12.004Z","requestId":"req_01J5X8ZC3K4T7Q9M2W6B0N1V4H"},"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not found","content":{"application/json":{"example":{"success":false,"error":"Resource not found","code":"NOT_FOUND","timestamp":"2026-08-19T09:41:12.004Z","requestId":"req_01J5X8ZC3K4T7Q9M2W6B0N1V4H"},"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limit exceeded","content":{"application/json":{"example":{"success":false,"error":"Too many requests","code":"TOO_MANY_REQUESTS","timestamp":"2026-08-19T09:41:12.004Z","requestId":"req_01J5X8ZC3K4T7Q9M2W6B0N1V4H"},"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}},"post":{"operationId":"postRiskScenarios","tags":["Risks"],"summary":"Create a risk scenario","description":"Creates a scenario in an existing register, which `registerId` must name — a register in another organization is refused 400, not 404, because the reference came from the body rather than the URL. The scenario is assigned the next `R-N` display id under that register and always starts `approvalStatus: \"draft\"`: approval is a state machine with its own endpoints, and a create that could land approved would be a sign-off nobody gave. `created_by` is left NULL for an API key — no user created the row — and the audit entry attributes the api_client instead.","security":[{"bearerAuth":["risks:write"]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"registerId":{"type":"string","format":"uuid"},"title":{"type":"string","minLength":1,"maxLength":255},"description":{"type":"string","maxLength":4000},"categoryId":{"type":["string","null"],"format":"uuid"},"riskType":{"type":"array","items":{"type":"string","enum":["confidentiality","integrity","availability"]},"maxItems":3},"inherentLikelihood":{"type":"integer","minimum":1,"maximum":5},"inherentImpact":{"type":"integer","minimum":1,"maximum":5},"residualLikelihood":{"type":"integer","minimum":1,"maximum":5},"residualImpact":{"type":"integer","minimum":1,"maximum":5},"lifecycleStatus":{"type":"string","enum":["open","mitigating","accepted","closed"]},"treatment":{"type":"string","enum":["mitigate","accept","transfer","avoid"]},"treatmentPlan":{"type":"string","maxLength":4000},"ownerUserId":{"type":["string","null"],"format":"uuid"},"targetResolutionDate":{"type":"string","format":"date"},"vendorId":{"type":["string","null"],"format":"uuid"},"businessFunctionId":{"type":["string","null"],"format":"uuid"},"businessUnitIds":{"type":"array","items":{"type":"string","format":"uuid"},"maxItems":100}},"required":["registerId","title"],"additionalProperties":false}}}},"responses":{"201":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","enum":[true]},"data":{"$ref":"#/components/schemas/RiskScenario"},"timestamp":{"type":"string","format":"date-time"},"requestId":{"type":"string"},"message":{"type":"string"}},"required":["success","data","timestamp"]},"example":{"success":true,"data":{"id":"a75196b5-1c70-4215-8ab8-08a2f5b59d52","organizationId":"836fb6d0-badc-4c96-8e96-0e8f9138e4d1","registerId":"e9369746-64f0-400c-8502-779d4be245db","displayId":"string","title":"string","description":"string","categoryId":"e36dbbe9-f0be-42f1-8e66-12f63cafd2f6","riskType":["confidentiality"],"inherentLikelihood":1,"inherentImpact":1,"residualLikelihood":1,"residualImpact":1,"lifecycleStatus":"open","approvalStatus":"draft","isArchived":true,"treatment":"mitigate","treatmentPlan":"string","ownerUserId":"5b3b4fdf-7b5e-48e7-8a1d-0eec03be7738","targetResolutionDate":"string","vendorId":"f7e40fe7-2105-457f-86e7-a2345ea45190","businessFunctionId":"9d8e6eff-0438-4847-894a-130c479bf598","controlId":"6ca5eea0-ab36-4906-8c0c-12df5201aec1","sourceTemplateId":"d25a7da4-ca73-4c52-854a-a383db7f6d85","businessUnitIds":["ffada0aa-2653-4878-8116-f9a1cc2afebf"],"createdBy":"14c317a7-541e-48bf-8793-4ff43ce6d6d0","createdAt":"2026-08-19T09:41:12.004Z","updatedAt":"2026-08-19T09:41:12.004Z","inherentScore":1,"residualScore":1},"timestamp":"2026-08-19T09:41:12.004Z","requestId":"req_01J5X8ZC3K4T7Q9M2W6B0N1V4H","message":"string"}}}},"400":{"description":"A body reference (registerId, categoryId, ownerUserId, vendorId, businessUnitIds) names a row outside this organization","content":{"application/json":{"example":{"success":false,"error":"Bad request","code":"BAD_REQUEST","timestamp":"2026-08-19T09:41:12.004Z","requestId":"req_01J5X8ZC3K4T7Q9M2W6B0N1V4H"},"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Unauthorized","content":{"application/json":{"example":{"success":false,"error":"Unauthorized","code":"UNAUTHORIZED","timestamp":"2026-08-19T09:41:12.004Z","requestId":"req_01J5X8ZC3K4T7Q9M2W6B0N1V4H"},"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Forbidden — missing scope","content":{"application/json":{"example":{"success":false,"error":"Forbidden","code":"FORBIDDEN","timestamp":"2026-08-19T09:41:12.004Z","requestId":"req_01J5X8ZC3K4T7Q9M2W6B0N1V4H"},"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not found","content":{"application/json":{"example":{"success":false,"error":"Resource not found","code":"NOT_FOUND","timestamp":"2026-08-19T09:41:12.004Z","requestId":"req_01J5X8ZC3K4T7Q9M2W6B0N1V4H"},"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"422":{"description":"Unrecognised or invalid field — the response names it","content":{"application/json":{"example":{"success":false,"error":"Validation failed","code":"VALIDATION_ERROR","timestamp":"2026-08-19T09:41:12.004Z","requestId":"req_01J5X8ZC3K4T7Q9M2W6B0N1V4H"},"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limit exceeded","content":{"application/json":{"example":{"success":false,"error":"Too many requests","code":"TOO_MANY_REQUESTS","timestamp":"2026-08-19T09:41:12.004Z","requestId":"req_01J5X8ZC3K4T7Q9M2W6B0N1V4H"},"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/risk-scenarios/{id}":{"get":{"operationId":"getRiskScenariosById","tags":["Risks"],"summary":"Get a risk scenario by id","security":[{"bearerAuth":["risks:read"]}],"parameters":[{"schema":{"type":"string","format":"uuid"},"required":true,"name":"id","in":"path"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","enum":[true]},"data":{"$ref":"#/components/schemas/RiskScenario"},"timestamp":{"type":"string","format":"date-time"},"requestId":{"type":"string"},"message":{"type":"string"}},"required":["success","data","timestamp"]},"example":{"success":true,"data":{"id":"9a99afc6-23ef-418c-8154-841d910bf35b","organizationId":"2dc05c1f-22d1-41a7-8305-952c39c9cdf8","registerId":"34178a81-840f-4c39-8db0-3f4e0673a17e","displayId":"string","title":"string","description":"string","categoryId":"f4ebd41e-ab3e-4814-8b07-5c356d962123","riskType":["confidentiality"],"inherentLikelihood":1,"inherentImpact":1,"residualLikelihood":1,"residualImpact":1,"lifecycleStatus":"open","approvalStatus":"draft","isArchived":true,"treatment":"mitigate","treatmentPlan":"string","ownerUserId":"7c4998f6-9bdb-481c-89fc-08cdd0c1d46b","targetResolutionDate":"string","vendorId":"a83c17a0-7899-4406-8e2c-e3df9baab1c1","businessFunctionId":"57dd38b8-0b40-4cce-8338-e6b745932bc9","controlId":"bfd887cd-d0dd-4add-8b26-5b7aeb62075a","sourceTemplateId":"50d3b5ef-2a47-4417-8262-8b7c19218de8","businessUnitIds":["042a1d93-1f4c-4b43-857f-35c0eb41a38c"],"createdBy":"0c2604e6-03d9-42ec-8eb4-ae3d2f6e43bb","createdAt":"2026-08-19T09:41:12.004Z","updatedAt":"2026-08-19T09:41:12.004Z","inherentScore":1,"residualScore":1},"timestamp":"2026-08-19T09:41:12.004Z","requestId":"req_01J5X8ZC3K4T7Q9M2W6B0N1V4H","message":"string"}}}},"400":{"description":"Validation error","content":{"application/json":{"example":{"success":false,"error":"Bad request","code":"BAD_REQUEST","timestamp":"2026-08-19T09:41:12.004Z","requestId":"req_01J5X8ZC3K4T7Q9M2W6B0N1V4H"},"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Unauthorized","content":{"application/json":{"example":{"success":false,"error":"Unauthorized","code":"UNAUTHORIZED","timestamp":"2026-08-19T09:41:12.004Z","requestId":"req_01J5X8ZC3K4T7Q9M2W6B0N1V4H"},"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Forbidden — missing scope","content":{"application/json":{"example":{"success":false,"error":"Forbidden","code":"FORBIDDEN","timestamp":"2026-08-19T09:41:12.004Z","requestId":"req_01J5X8ZC3K4T7Q9M2W6B0N1V4H"},"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not found","content":{"application/json":{"example":{"success":false,"error":"Resource not found","code":"NOT_FOUND","timestamp":"2026-08-19T09:41:12.004Z","requestId":"req_01J5X8ZC3K4T7Q9M2W6B0N1V4H"},"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limit exceeded","content":{"application/json":{"example":{"success":false,"error":"Too many requests","code":"TOO_MANY_REQUESTS","timestamp":"2026-08-19T09:41:12.004Z","requestId":"req_01J5X8ZC3K4T7Q9M2W6B0N1V4H"},"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}},"put":{"operationId":"putRiskScenariosById","tags":["Risks"],"summary":"Update a risk scenario","description":"Patches a scenario's content. A submitted value that EQUALS the stored one is not a change: a request in which nothing differs writes no row, bumps no `updatedAt` and files no audit entry. Pass the optional `expectedUpdatedAt` precondition (ADR-0022) to be refused **409 `RECORD_MODIFIED`** rather than overwrite an edit that landed since you read the record; omitting it is last-write-wins, unchanged. **Editing an approved scenario returns it to `needs_review` and discards its approvals** — a decision describes a record, and the record moved. `approvalStatus` and `isArchived` are refused: both are transitions with their own endpoints.","security":[{"bearerAuth":["risks:write"]}],"parameters":[{"schema":{"type":"string","format":"uuid"},"required":true,"name":"id","in":"path"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"title":{"type":"string","minLength":1,"maxLength":255},"description":{"type":"string","maxLength":4000},"categoryId":{"type":["string","null"],"format":"uuid"},"riskType":{"type":["array","null"],"items":{"type":"string","enum":["confidentiality","integrity","availability"]},"maxItems":3},"inherentLikelihood":{"type":["integer","null"],"minimum":1,"maximum":5},"inherentImpact":{"type":["integer","null"],"minimum":1,"maximum":5},"residualLikelihood":{"type":["integer","null"],"minimum":1,"maximum":5},"residualImpact":{"type":["integer","null"],"minimum":1,"maximum":5},"lifecycleStatus":{"type":"string","enum":["open","mitigating","accepted","closed"]},"treatment":{"type":["string","null"],"enum":["mitigate","accept","transfer","avoid",null]},"treatmentPlan":{"type":"string","maxLength":4000},"ownerUserId":{"type":["string","null"],"format":"uuid"},"targetResolutionDate":{"type":["string","null"],"format":"date"},"vendorId":{"type":["string","null"],"format":"uuid"},"businessFunctionId":{"type":["string","null"],"format":"uuid"},"controlId":{"type":["string","null"],"format":"uuid"},"businessUnitIds":{"type":"array","items":{"type":"string","format":"uuid"},"maxItems":100},"expectedUpdatedAt":{"type":"string","format":"date-time"}},"additionalProperties":false}}}},"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","enum":[true]},"data":{"$ref":"#/components/schemas/RiskScenario"},"timestamp":{"type":"string","format":"date-time"},"requestId":{"type":"string"},"message":{"type":"string"}},"required":["success","data","timestamp"]},"example":{"success":true,"data":{"id":"21101191-9f4b-4a69-8e1d-44de7213632e","organizationId":"59c6770c-616d-4b0a-883f-7f2b4af536fd","registerId":"bd3bb052-34f6-4df0-8321-75896aac0cf7","displayId":"string","title":"string","description":"string","categoryId":"3d623995-38a0-48b5-8ae9-968223b7f4f2","riskType":["confidentiality"],"inherentLikelihood":1,"inherentImpact":1,"residualLikelihood":1,"residualImpact":1,"lifecycleStatus":"open","approvalStatus":"draft","isArchived":true,"treatment":"mitigate","treatmentPlan":"string","ownerUserId":"48f20193-65f8-4743-8623-b9c0ae3d6f8c","targetResolutionDate":"string","vendorId":"9b61e63b-d41d-4bbb-8250-92a830d6e4c4","businessFunctionId":"8f883923-1471-4ef3-8f5b-23d0307966bc","controlId":"540c8a1c-6dbd-4d3a-8a32-f0bb9d30fcad","sourceTemplateId":"37896b88-f754-4a3e-86b0-de073b6d7eb9","businessUnitIds":["09f21e56-fc25-4e3c-8e6a-7d2d3aa3078b"],"createdBy":"fd7d4923-2d3a-4ef3-827e-b3d0217516bc","createdAt":"2026-08-19T09:41:12.004Z","updatedAt":"2026-08-19T09:41:12.004Z","inherentScore":1,"residualScore":1},"timestamp":"2026-08-19T09:41:12.004Z","requestId":"req_01J5X8ZC3K4T7Q9M2W6B0N1V4H","message":"string"}}}},"400":{"description":"Validation error","content":{"application/json":{"example":{"success":false,"error":"Bad request","code":"BAD_REQUEST","timestamp":"2026-08-19T09:41:12.004Z","requestId":"req_01J5X8ZC3K4T7Q9M2W6B0N1V4H"},"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Unauthorized","content":{"application/json":{"example":{"success":false,"error":"Unauthorized","code":"UNAUTHORIZED","timestamp":"2026-08-19T09:41:12.004Z","requestId":"req_01J5X8ZC3K4T7Q9M2W6B0N1V4H"},"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Forbidden — missing scope","content":{"application/json":{"example":{"success":false,"error":"Forbidden","code":"FORBIDDEN","timestamp":"2026-08-19T09:41:12.004Z","requestId":"req_01J5X8ZC3K4T7Q9M2W6B0N1V4H"},"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"No such scenario in this organization","content":{"application/json":{"example":{"success":false,"error":"Resource not found","code":"NOT_FOUND","timestamp":"2026-08-19T09:41:12.004Z","requestId":"req_01J5X8ZC3K4T7Q9M2W6B0N1V4H"},"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"The record changed since `expectedUpdatedAt` (`RECORD_MODIFIED`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"422":{"description":"Unrecognised or invalid field — the response names it","content":{"application/json":{"example":{"success":false,"error":"Validation failed","code":"VALIDATION_ERROR","timestamp":"2026-08-19T09:41:12.004Z","requestId":"req_01J5X8ZC3K4T7Q9M2W6B0N1V4H"},"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limit exceeded","content":{"application/json":{"example":{"success":false,"error":"Too many requests","code":"TOO_MANY_REQUESTS","timestamp":"2026-08-19T09:41:12.004Z","requestId":"req_01J5X8ZC3K4T7Q9M2W6B0N1V4H"},"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/trust-center/access-requests":{"get":{"operationId":"getTrustCenterAccessRequests","tags":["Trust Center"],"summary":"List Trust Center access requests","description":"Requests for gated Trust Center documents, newest first, offset-paginated. Filter by `status` (`pending` | `approved` | `rejected` | `auto_approved`) — `auto_approved` is a standing rule deciding on the organization's behalf, and is a different fact from a person approving, which is why it is its own value rather than an `approved` row with a flag. Every identifying field on a request is SELF-ASSERTED by an anonymous submitter: the name, the address and the employer are all typed in by whoever filled the form, and only the observed country/city are not. Treat the row as a claim, which is what the reviewer in the app is doing.","security":[{"bearerAuth":["trust-center-access:read"]}],"parameters":[{"schema":{"type":"integer","minimum":1,"maximum":10000,"default":1},"required":false,"name":"page","in":"query"},{"schema":{"type":"integer","minimum":1,"maximum":500,"default":100},"required":false,"name":"limit","in":"query"},{"schema":{"type":"string","enum":["pending","approved","rejected","auto_approved"]},"required":false,"name":"status","in":"query"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","enum":[true]},"data":{"type":"array","items":{"$ref":"#/components/schemas/TrustCenterAccessRequest"}},"timestamp":{"type":"string","format":"date-time"},"requestId":{"type":"string"},"message":{"type":"string"},"pagination":{"$ref":"#/components/schemas/Pagination"}},"required":["success","data","timestamp"]},"example":{"success":true,"data":[{"id":"10aac583-bdd4-4a13-862c-77308bffa6dc","organizationId":"7a89f8a2-8732-43e0-8753-3e59f50b2c67","visitorEmail":"string","visitorName":"string","companyName":"string","reason":"string","rejectionReason":"string","status":"string","decidedByUserId":"26aceadb-bb35-439b-8d89-b8485bcd1fa4","decidedAt":"2026-08-19T09:41:12.004Z","autoRuleId":"af7df374-b946-42c2-8a9b-15d3a9236175","visitorTokenId":"469e236e-96f1-4304-8596-0405ac284d93","requestCountryCode":"string","requestCity":"string","createdAt":"2026-08-19T09:41:12.004Z"}],"timestamp":"2026-08-19T09:41:12.004Z","requestId":"req_01J5X8ZC3K4T7Q9M2W6B0N1V4H","message":"string","pagination":{"page":1,"limit":1,"total":1,"totalPages":1}}}}},"400":{"description":"Validation error","content":{"application/json":{"example":{"success":false,"error":"Bad request","code":"BAD_REQUEST","timestamp":"2026-08-19T09:41:12.004Z","requestId":"req_01J5X8ZC3K4T7Q9M2W6B0N1V4H"},"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Unauthorized","content":{"application/json":{"example":{"success":false,"error":"Unauthorized","code":"UNAUTHORIZED","timestamp":"2026-08-19T09:41:12.004Z","requestId":"req_01J5X8ZC3K4T7Q9M2W6B0N1V4H"},"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Forbidden — missing scope","content":{"application/json":{"example":{"success":false,"error":"Forbidden","code":"FORBIDDEN","timestamp":"2026-08-19T09:41:12.004Z","requestId":"req_01J5X8ZC3K4T7Q9M2W6B0N1V4H"},"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not found","content":{"application/json":{"example":{"success":false,"error":"Resource not found","code":"NOT_FOUND","timestamp":"2026-08-19T09:41:12.004Z","requestId":"req_01J5X8ZC3K4T7Q9M2W6B0N1V4H"},"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limit exceeded","content":{"application/json":{"example":{"success":false,"error":"Too many requests","code":"TOO_MANY_REQUESTS","timestamp":"2026-08-19T09:41:12.004Z","requestId":"req_01J5X8ZC3K4T7Q9M2W6B0N1V4H"},"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/trust-center/resources":{"get":{"operationId":"getTrustCenterResources","tags":["Trust Center"],"summary":"List Trust Center resources","description":"The document catalogue published on the organization's Trust Center, in display order. Pass `?published=true` for only the live ones — without it drafts are included, which is what an editor syncing their own copy wants and what a public mirror does not. `isGated` is the line between a document anyone can read and one behind the NDA. Unpaginated: this is a hand-curated list with an explicit `sortOrder`, the same set the public page renders in full, so it is bounded by construction in a way the visitor-derived registers below are not. The blob's storage key is deliberately not published — it is an internal vault location that grants nothing and belongs to no caller.","security":[{"bearerAuth":["trust-center-content:read"]}],"parameters":[{"schema":{"type":"string","enum":["true","false"]},"required":false,"name":"published","in":"query"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","enum":[true]},"data":{"type":"array","items":{"$ref":"#/components/schemas/TrustCenterResource"}},"timestamp":{"type":"string","format":"date-time"},"requestId":{"type":"string"},"message":{"type":"string"}},"required":["success","data","timestamp"]},"example":{"success":true,"data":[{"id":"b06ef84d-0db0-445d-8b77-7ffaab1e7cda","organizationId":"81ff3618-bec2-4aee-88a9-931745f286e9","title":"string","description":"string","category":"string","sourceType":"string","externalUrl":"string","fileId":"092d973b-abc5-4ebb-8f36-2ba8ce46bfc4","isGated":true,"isPublished":true,"sortOrder":1,"createdAt":"2026-08-19T09:41:12.004Z","updatedAt":"2026-08-19T09:41:12.004Z"}],"timestamp":"2026-08-19T09:41:12.004Z","requestId":"req_01J5X8ZC3K4T7Q9M2W6B0N1V4H","message":"string"}}}},"400":{"description":"Validation error","content":{"application/json":{"example":{"success":false,"error":"Bad request","code":"BAD_REQUEST","timestamp":"2026-08-19T09:41:12.004Z","requestId":"req_01J5X8ZC3K4T7Q9M2W6B0N1V4H"},"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Unauthorized","content":{"application/json":{"example":{"success":false,"error":"Unauthorized","code":"UNAUTHORIZED","timestamp":"2026-08-19T09:41:12.004Z","requestId":"req_01J5X8ZC3K4T7Q9M2W6B0N1V4H"},"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Forbidden — missing scope","content":{"application/json":{"example":{"success":false,"error":"Forbidden","code":"FORBIDDEN","timestamp":"2026-08-19T09:41:12.004Z","requestId":"req_01J5X8ZC3K4T7Q9M2W6B0N1V4H"},"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not found","content":{"application/json":{"example":{"success":false,"error":"Resource not found","code":"NOT_FOUND","timestamp":"2026-08-19T09:41:12.004Z","requestId":"req_01J5X8ZC3K4T7Q9M2W6B0N1V4H"},"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limit exceeded","content":{"application/json":{"example":{"success":false,"error":"Too many requests","code":"TOO_MANY_REQUESTS","timestamp":"2026-08-19T09:41:12.004Z","requestId":"req_01J5X8ZC3K4T7Q9M2W6B0N1V4H"},"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/trust-center/subscribers":{"get":{"operationId":"getTrustCenterSubscribers","tags":["Trust Center"],"summary":"List Trust Center subscribers","description":"The addresses that asked to hear about changes to this organization's Trust Center, offset-paginated. Filter by `status` (`pending` | `verified` | `unsubscribed`) and by `source` (`public` — the visitor's own double opt-in — or `manual`, typed in by an operator). The two are orthogonal, so \"who did we add ourselves, and are they still on the list\" is one request. This is a register of CONSENTS: an unsubscribed row is retained rather than deleted, because the withdrawal is the half of the record a controller has to be able to produce.","security":[{"bearerAuth":["trust-center-subscribers:read"]}],"parameters":[{"schema":{"type":"integer","minimum":1,"maximum":10000,"default":1},"required":false,"name":"page","in":"query"},{"schema":{"type":"integer","minimum":1,"maximum":500,"default":100},"required":false,"name":"limit","in":"query"},{"schema":{"type":"string","enum":["createdAt","email","verifiedAt"]},"required":false,"name":"sortBy","in":"query"},{"schema":{"type":"string","enum":["asc","desc"],"default":"desc"},"required":false,"name":"sortOrder","in":"query"},{"schema":{"type":"string","minLength":1,"maxLength":255},"required":false,"name":"search","in":"query"},{"schema":{"type":["array","null"],"items":{"type":"string","enum":["pending","verified","unsubscribed"]},"maxItems":100},"required":false,"name":"status","in":"query"},{"schema":{"type":["array","null"],"items":{"type":"string","enum":["public","manual"]},"maxItems":100},"required":false,"name":"source","in":"query"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","enum":[true]},"data":{"type":"array","items":{"$ref":"#/components/schemas/TrustCenterSubscriber"}},"timestamp":{"type":"string","format":"date-time"},"requestId":{"type":"string"},"message":{"type":"string"},"pagination":{"$ref":"#/components/schemas/Pagination"}},"required":["success","data","timestamp"]},"example":{"success":true,"data":[{"id":"c3c02acb-f083-4a6b-86c7-51b867c5aaf4","email":"string","status":"string","source":"string","scopes":["string"],"verifiedAt":"2026-08-19T09:41:12.004Z","createdAt":"2026-08-19T09:41:12.004Z"}],"timestamp":"2026-08-19T09:41:12.004Z","requestId":"req_01J5X8ZC3K4T7Q9M2W6B0N1V4H","message":"string","pagination":{"page":1,"limit":1,"total":1,"totalPages":1}}}}},"400":{"description":"Validation error","content":{"application/json":{"example":{"success":false,"error":"Bad request","code":"BAD_REQUEST","timestamp":"2026-08-19T09:41:12.004Z","requestId":"req_01J5X8ZC3K4T7Q9M2W6B0N1V4H"},"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Unauthorized","content":{"application/json":{"example":{"success":false,"error":"Unauthorized","code":"UNAUTHORIZED","timestamp":"2026-08-19T09:41:12.004Z","requestId":"req_01J5X8ZC3K4T7Q9M2W6B0N1V4H"},"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Forbidden — missing scope","content":{"application/json":{"example":{"success":false,"error":"Forbidden","code":"FORBIDDEN","timestamp":"2026-08-19T09:41:12.004Z","requestId":"req_01J5X8ZC3K4T7Q9M2W6B0N1V4H"},"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not found","content":{"application/json":{"example":{"success":false,"error":"Resource not found","code":"NOT_FOUND","timestamp":"2026-08-19T09:41:12.004Z","requestId":"req_01J5X8ZC3K4T7Q9M2W6B0N1V4H"},"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limit exceeded","content":{"application/json":{"example":{"success":false,"error":"Too many requests","code":"TOO_MANY_REQUESTS","timestamp":"2026-08-19T09:41:12.004Z","requestId":"req_01J5X8ZC3K4T7Q9M2W6B0N1V4H"},"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/trust-center/visitor-tokens":{"get":{"operationId":"getTrustCenterVisitorTokens","tags":["Trust Center"],"summary":"List Trust Center visitor tokens","description":"Who currently holds a credential to the gated half of the Trust Center, newest first, offset-paginated — the access review a security team runs against its own document vault. **No token material is returned, ever.** The raw token is one-shot (minted, mailed to the visitor, discarded); storage is a sha256 hash, and that hash is not published either. `tokenSuffix` is always null and exists so the shape does not change if a fragment is ever stored. `status` is `active` | `expired` | `revoked` — the answerable vocabulary. `expired` is DERIVED from `expiresAt`, so a token becomes expired with no row ever changing, which is why there is no status filter: a filter over a value computed after the page was cut returns short pages.","security":[{"bearerAuth":["trust-center-access:read"]}],"parameters":[{"schema":{"type":"integer","minimum":1,"maximum":10000,"default":1},"required":false,"name":"page","in":"query"},{"schema":{"type":"integer","minimum":1,"maximum":500,"default":100},"required":false,"name":"limit","in":"query"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","enum":[true]},"data":{"type":"array","items":{"$ref":"#/components/schemas/TrustCenterVisitorToken"}},"timestamp":{"type":"string","format":"date-time"},"requestId":{"type":"string"},"message":{"type":"string"},"pagination":{"$ref":"#/components/schemas/Pagination"}},"required":["success","data","timestamp"]},"example":{"success":true,"data":[{"id":"c5610b5d-16c4-468d-85f6-f18a11be428a","organizationId":"86e5d148-a5c8-477e-8794-19c701248df9","origin":"string","visitorEmail":"string","visitorName":"string","companyName":"string","tokenSuffix":"string","status":"active","expiresAt":"2026-08-19T09:41:12.004Z","revokedAt":"2026-08-19T09:41:12.004Z","lastUsedAt":"2026-08-19T09:41:12.004Z","createdAt":"2026-08-19T09:41:12.004Z","updatedAt":"2026-08-19T09:41:12.004Z"}],"timestamp":"2026-08-19T09:41:12.004Z","requestId":"req_01J5X8ZC3K4T7Q9M2W6B0N1V4H","message":"string","pagination":{"page":1,"limit":1,"total":1,"totalPages":1}}}}},"400":{"description":"Validation error","content":{"application/json":{"example":{"success":false,"error":"Bad request","code":"BAD_REQUEST","timestamp":"2026-08-19T09:41:12.004Z","requestId":"req_01J5X8ZC3K4T7Q9M2W6B0N1V4H"},"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Unauthorized","content":{"application/json":{"example":{"success":false,"error":"Unauthorized","code":"UNAUTHORIZED","timestamp":"2026-08-19T09:41:12.004Z","requestId":"req_01J5X8ZC3K4T7Q9M2W6B0N1V4H"},"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Forbidden — missing scope","content":{"application/json":{"example":{"success":false,"error":"Forbidden","code":"FORBIDDEN","timestamp":"2026-08-19T09:41:12.004Z","requestId":"req_01J5X8ZC3K4T7Q9M2W6B0N1V4H"},"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not found","content":{"application/json":{"example":{"success":false,"error":"Resource not found","code":"NOT_FOUND","timestamp":"2026-08-19T09:41:12.004Z","requestId":"req_01J5X8ZC3K4T7Q9M2W6B0N1V4H"},"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limit exceeded","content":{"application/json":{"example":{"success":false,"error":"Too many requests","code":"TOO_MANY_REQUESTS","timestamp":"2026-08-19T09:41:12.004Z","requestId":"req_01J5X8ZC3K4T7Q9M2W6B0N1V4H"},"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/vendors":{"get":{"operationId":"getVendors","tags":["Vendors"],"summary":"List vendors","security":[{"bearerAuth":["vendors:read"]}],"parameters":[{"schema":{"type":"integer","minimum":1,"maximum":10000,"default":1},"required":false,"name":"page","in":"query"},{"schema":{"type":"integer","minimum":1,"maximum":500,"default":100},"required":false,"name":"limit","in":"query"},{"schema":{"type":"string"},"required":false,"name":"sortBy","in":"query"},{"schema":{"type":"string","enum":["asc","desc"],"default":"desc"},"required":false,"name":"sortOrder","in":"query"},{"schema":{"type":"string","minLength":1,"maxLength":255},"required":false,"name":"search","in":"query"},{"schema":{"type":"string"},"required":false,"name":"name","in":"query"},{"schema":{"type":"string"},"required":false,"name":"country","in":"query"},{"schema":{"type":"string","format":"uuid"},"required":false,"name":"criticalityTierId","in":"query"},{"schema":{"type":"string","enum":["procurement","active","archived"]},"required":false,"name":"state","in":"query"},{"schema":{"type":["string","null"],"enum":["true","false","all",null]},"required":false,"name":"directlyEngaged","in":"query"},{"schema":{"type":"string","format":"uuid"},"required":false,"name":"categoryId","in":"query"},{"schema":{"type":"string","format":"uuid"},"required":false,"name":"securityOwnerId","in":"query"},{"schema":{"type":"string","format":"uuid"},"required":false,"name":"businessOwnerId","in":"query"},{"schema":{"type":["string","null"],"enum":["true","false","all",null]},"required":false,"name":"hasSecurityOwner","in":"query"},{"schema":{"type":["string","null"],"enum":["true","false","all",null]},"required":false,"name":"hasBusinessOwner","in":"query"},{"schema":{"type":["array","null"],"items":{"type":"string"},"maxItems":100},"required":false,"name":"riskBand","in":"query"},{"schema":{"type":["string","null"],"enum":["true","false","all",null]},"required":false,"name":"riskScored","in":"query"},{"schema":{"type":["array","null"],"items":{"type":"string","enum":["not_required","pending","approved"]},"maxItems":100},"required":false,"name":"riskApproval","in":"query"},{"schema":{"type":"string","format":"uuid"},"required":false,"name":"businessUnitId","in":"query"},{"schema":{"type":"string"},"required":false,"name":"createdFrom","in":"query"},{"schema":{"type":"string"},"required":false,"name":"createdTo","in":"query"},{"schema":{"type":"string"},"required":false,"name":"createdAfter","in":"query"},{"schema":{"type":"string"},"required":false,"name":"createdBefore","in":"query"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","enum":[true]},"data":{"type":"array","items":{"$ref":"#/components/schemas/Vendor"}},"timestamp":{"type":"string","format":"date-time"},"requestId":{"type":"string"},"message":{"type":"string"},"pagination":{"$ref":"#/components/schemas/Pagination"}},"required":["success","data","timestamp"]},"example":{"success":true,"data":[{"id":"8d186188-a761-4c3e-8b8f-c407465190b9","organizationId":"aa09c50d-bc61-469d-8b08-faba7d22b91a","displayId":"string","name":"string","state":"procurement","directlyEngaged":true,"vatNumber":"string","countryCode":"string","description":"string","website":"string","category":"string","categoryId":"5c819b00-a207-4426-860b-863f4f244ee1","headquartersCountryCode":"string","authMethod":"sso_oidc","servicesProvided":"string","securityOwnerId":"4da8ab9b-d986-41db-8627-47087bd4d7e4","businessOwnerId":"7dc40657-5095-47cf-8815-1624b931d460","notes":"string","lastAssessedAt":"2026-08-19T09:41:12.004Z","criticalityTierId":"4b1671d5-0b55-4575-8d23-28c234592fb2","lei":"string","euId":"string","legalPersonType":"legal_person","countryOfRegistration":"string","parentLei":"string","parentName":"string","headOfficeAddress":"string","inherentRiskScore":"string","inherentRiskBand":"string","inherentRiskScoredAt":"2026-08-19T09:41:12.004Z","inherentRiskApprovalStatus":"string","inherentRiskBandOverride":"string","inherentRiskSignedOffAt":"2026-08-19T09:41:12.004Z","inherentRiskSignedOffBy":"752c3e27-99a5-443f-8c0d-1a7498a09e50","inherentRiskAnswersFingerprint":"string","annualExpense":"string","approvalStatus":"string","approvalInstanceId":"9038eea0-ab9f-4906-8157-12df8712aec1","businessUnitIds":["c66d6881-e13b-4639-8ab4-4d4e63d5ab7e"],"createdAt":"2026-08-19T09:41:12.004Z","updatedAt":"2026-08-19T09:41:12.004Z"}],"timestamp":"2026-08-19T09:41:12.004Z","requestId":"req_01J5X8ZC3K4T7Q9M2W6B0N1V4H","message":"string","pagination":{"page":1,"limit":1,"total":1,"totalPages":1}}}}},"400":{"description":"Validation error","content":{"application/json":{"example":{"success":false,"error":"Bad request","code":"BAD_REQUEST","timestamp":"2026-08-19T09:41:12.004Z","requestId":"req_01J5X8ZC3K4T7Q9M2W6B0N1V4H"},"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Unauthorized","content":{"application/json":{"example":{"success":false,"error":"Unauthorized","code":"UNAUTHORIZED","timestamp":"2026-08-19T09:41:12.004Z","requestId":"req_01J5X8ZC3K4T7Q9M2W6B0N1V4H"},"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Forbidden — missing scope","content":{"application/json":{"example":{"success":false,"error":"Forbidden","code":"FORBIDDEN","timestamp":"2026-08-19T09:41:12.004Z","requestId":"req_01J5X8ZC3K4T7Q9M2W6B0N1V4H"},"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not found","content":{"application/json":{"example":{"success":false,"error":"Resource not found","code":"NOT_FOUND","timestamp":"2026-08-19T09:41:12.004Z","requestId":"req_01J5X8ZC3K4T7Q9M2W6B0N1V4H"},"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limit exceeded","content":{"application/json":{"example":{"success":false,"error":"Too many requests","code":"TOO_MANY_REQUESTS","timestamp":"2026-08-19T09:41:12.004Z","requestId":"req_01J5X8ZC3K4T7Q9M2W6B0N1V4H"},"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/vendors/imports":{"post":{"operationId":"postVendorsImports","tags":["Vendors"],"summary":"Bulk vendor ingest","description":"Programmatic bulk import: rows keyed by importable vendor field names (plus custom:<code> for assigned custom fields), string cell values. Runs the same reference-aware validate → dedupe → commit pipeline as the import wizard, mints an IMP-{n} history entry, and respects the plan’s per-import row quota. matchKey.mode upsert updates existing matches (blank cells never overwrite); enrich=true fills empty countryOfRegistration from GLEIF on checksum-valid LEIs (bounded, best-effort). Requires the vendors.bulk_import and vendors.import_integrations plan features (402 otherwise). Synchronous: the outcome (imported/updated/skipped/failed + per-row errors) is in the response.","security":[{"bearerAuth":["vendors:write"]}],"requestBody":{"description":"Vendor rows + options","required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"label":{"type":"string","minLength":1,"maxLength":255},"matchKey":{"type":"object","properties":{"key":{"type":"string","enum":["name","website","vatNumber","lei"],"default":"name"},"mode":{"type":"string","enum":["create-only","upsert"],"default":"create-only"}}},"enrich":{"type":"boolean"},"vendors":{"type":"array","items":{"type":"object","additionalProperties":{"type":"string","maxLength":4000}},"minItems":1,"maxItems":10000}},"required":["vendors"]}}}},"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","enum":[true]},"data":{"type":"object","properties":{"job":{"$ref":"#/components/schemas/VendorImportJob"},"summary":{"type":"object","properties":{"imported":{"type":"integer"},"updated":{"type":"integer"},"skipped":{"type":"integer"},"failed":{"type":"integer"}},"required":["imported","updated","skipped","failed"]}},"required":["job","summary"]},"timestamp":{"type":"string","format":"date-time"},"requestId":{"type":"string"},"message":{"type":"string"}},"required":["success","data","timestamp"]},"example":{"success":true,"data":{"job":{"id":"f00e1550-382b-4016-8193-d10f06b21451","displayId":"string","status":"string","rowsTotal":1,"rowsImported":1,"rowsUpdated":1,"rowsSkipped":1,"rowsFailed":1},"summary":{"imported":1,"updated":1,"skipped":1,"failed":1}},"timestamp":"2026-08-19T09:41:12.004Z","requestId":"req_01J5X8ZC3K4T7Q9M2W6B0N1V4H","message":"string"}}}},"400":{"description":"Validation error","content":{"application/json":{"example":{"success":false,"error":"Bad request","code":"BAD_REQUEST","timestamp":"2026-08-19T09:41:12.004Z","requestId":"req_01J5X8ZC3K4T7Q9M2W6B0N1V4H"},"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Unauthorized","content":{"application/json":{"example":{"success":false,"error":"Unauthorized","code":"UNAUTHORIZED","timestamp":"2026-08-19T09:41:12.004Z","requestId":"req_01J5X8ZC3K4T7Q9M2W6B0N1V4H"},"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Forbidden — missing scope","content":{"application/json":{"example":{"success":false,"error":"Forbidden","code":"FORBIDDEN","timestamp":"2026-08-19T09:41:12.004Z","requestId":"req_01J5X8ZC3K4T7Q9M2W6B0N1V4H"},"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not found","content":{"application/json":{"example":{"success":false,"error":"Resource not found","code":"NOT_FOUND","timestamp":"2026-08-19T09:41:12.004Z","requestId":"req_01J5X8ZC3K4T7Q9M2W6B0N1V4H"},"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limit exceeded","content":{"application/json":{"example":{"success":false,"error":"Too many requests","code":"TOO_MANY_REQUESTS","timestamp":"2026-08-19T09:41:12.004Z","requestId":"req_01J5X8ZC3K4T7Q9M2W6B0N1V4H"},"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/vendors/{id}":{"get":{"operationId":"getVendorsById","tags":["Vendors"],"summary":"Get a vendor by id","security":[{"bearerAuth":["vendors:read"]}],"parameters":[{"schema":{"type":"string","format":"uuid"},"required":true,"name":"id","in":"path"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","enum":[true]},"data":{"$ref":"#/components/schemas/Vendor"},"timestamp":{"type":"string","format":"date-time"},"requestId":{"type":"string"},"message":{"type":"string"}},"required":["success","data","timestamp"]},"example":{"success":true,"data":{"id":"988b2ec0-e51a-4b66-8de2-9fffd6c1d821","organizationId":"e0324e15-0630-4e35-8506-ff02c0037672","displayId":"string","name":"string","state":"procurement","directlyEngaged":true,"vatNumber":"string","countryCode":"string","description":"string","website":"string","category":"string","categoryId":"e89a58b8-e4f9-4cce-820b-06b7aa5b8bc9","headquartersCountryCode":"string","authMethod":"sso_oidc","servicesProvided":"string","securityOwnerId":"f3647023-481c-43f3-84e3-b2d0d67283bc","businessOwnerId":"de0d581f-ac01-45a7-8ab0-f12c1c8ba1f8","notes":"string","lastAssessedAt":"2026-08-19T09:41:12.004Z","criticalityTierId":"b748b0bd-466e-4cad-8d89-85eabd7dd5aa","lei":"string","euId":"string","legalPersonType":"legal_person","countryOfRegistration":"string","parentLei":"string","parentName":"string","headOfficeAddress":"string","inherentRiskScore":"string","inherentRiskBand":"string","inherentRiskScoredAt":"2026-08-19T09:41:12.004Z","inherentRiskApprovalStatus":"string","inherentRiskBandOverride":"string","inherentRiskSignedOffAt":"2026-08-19T09:41:12.004Z","inherentRiskSignedOffBy":"2f693f9f-3faf-4427-84b5-e4ac3256f478","inherentRiskAnswersFingerprint":"string","annualExpense":"string","approvalStatus":"string","approvalInstanceId":"c9ea5ee8-c5f3-4a5e-8b30-7067d040ebd9","businessUnitIds":["0e0bd2a9-c79c-4331-8d94-e7b63368bd36"],"createdAt":"2026-08-19T09:41:12.004Z","updatedAt":"2026-08-19T09:41:12.004Z"},"timestamp":"2026-08-19T09:41:12.004Z","requestId":"req_01J5X8ZC3K4T7Q9M2W6B0N1V4H","message":"string"}}}},"400":{"description":"Validation error","content":{"application/json":{"example":{"success":false,"error":"Bad request","code":"BAD_REQUEST","timestamp":"2026-08-19T09:41:12.004Z","requestId":"req_01J5X8ZC3K4T7Q9M2W6B0N1V4H"},"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Unauthorized","content":{"application/json":{"example":{"success":false,"error":"Unauthorized","code":"UNAUTHORIZED","timestamp":"2026-08-19T09:41:12.004Z","requestId":"req_01J5X8ZC3K4T7Q9M2W6B0N1V4H"},"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Forbidden — missing scope","content":{"application/json":{"example":{"success":false,"error":"Forbidden","code":"FORBIDDEN","timestamp":"2026-08-19T09:41:12.004Z","requestId":"req_01J5X8ZC3K4T7Q9M2W6B0N1V4H"},"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not found","content":{"application/json":{"example":{"success":false,"error":"Resource not found","code":"NOT_FOUND","timestamp":"2026-08-19T09:41:12.004Z","requestId":"req_01J5X8ZC3K4T7Q9M2W6B0N1V4H"},"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limit exceeded","content":{"application/json":{"example":{"success":false,"error":"Too many requests","code":"TOO_MANY_REQUESTS","timestamp":"2026-08-19T09:41:12.004Z","requestId":"req_01J5X8ZC3K4T7Q9M2W6B0N1V4H"},"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/webhooks":{"get":{"operationId":"getWebhooks","tags":["Webhooks"],"summary":"List the org’s outbound webhooks","security":[{"bearerAuth":["webhooks:read"]}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","enum":[true]},"data":{"type":"array","items":{"$ref":"#/components/schemas/Webhook"}},"timestamp":{"type":"string","format":"date-time"},"requestId":{"type":"string"},"message":{"type":"string"}},"required":["success","data","timestamp"]},"example":{"success":true,"data":[{"id":"899d4dcd-71a1-4cdd-8f37-917a827a095a","organizationId":"9b459398-0887-4b6e-8a14-ec97e1f06b69","name":"string","trigger":"string","endpoint":"https://example.com","status":"active","apiVersion":"string","customHeaders":[{"name":"string","valueHint":"string"}],"signing":{"enabled":true,"secretHint":"string"},"consecutiveFailures":1,"lastSuccessAt":"2026-08-19T09:41:12.004Z","lastFailureAt":"2026-08-19T09:41:12.004Z","disabledReason":"string","createdAt":"2026-08-19T09:41:12.004Z","updatedAt":"2026-08-19T09:41:12.004Z"}],"timestamp":"2026-08-19T09:41:12.004Z","requestId":"req_01J5X8ZC3K4T7Q9M2W6B0N1V4H","message":"string"}}}},"400":{"description":"Validation error","content":{"application/json":{"example":{"success":false,"error":"Bad request","code":"BAD_REQUEST","timestamp":"2026-08-19T09:41:12.004Z","requestId":"req_01J5X8ZC3K4T7Q9M2W6B0N1V4H"},"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Unauthorized","content":{"application/json":{"example":{"success":false,"error":"Unauthorized","code":"UNAUTHORIZED","timestamp":"2026-08-19T09:41:12.004Z","requestId":"req_01J5X8ZC3K4T7Q9M2W6B0N1V4H"},"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Forbidden — missing scope","content":{"application/json":{"example":{"success":false,"error":"Forbidden","code":"FORBIDDEN","timestamp":"2026-08-19T09:41:12.004Z","requestId":"req_01J5X8ZC3K4T7Q9M2W6B0N1V4H"},"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not found","content":{"application/json":{"example":{"success":false,"error":"Resource not found","code":"NOT_FOUND","timestamp":"2026-08-19T09:41:12.004Z","requestId":"req_01J5X8ZC3K4T7Q9M2W6B0N1V4H"},"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limit exceeded","content":{"application/json":{"example":{"success":false,"error":"Too many requests","code":"TOO_MANY_REQUESTS","timestamp":"2026-08-19T09:41:12.004Z","requestId":"req_01J5X8ZC3K4T7Q9M2W6B0N1V4H"},"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}},"post":{"operationId":"postWebhooks","tags":["Webhooks"],"summary":"Create an outbound webhook","description":"Creates one webhook entry (name + trigger + endpoint + optional custom headers + optional HMAC signing). The trigger must be available on the org’s plan (see GET /webhooks/triggers); the endpoint must be a public HTTPS URL (private / loopback / metadata addresses are rejected). When `signingEnabled` is true the response carries `signingSecret` exactly once. Subject to the plan’s webhook-count cap (409 when exceeded).","security":[{"bearerAuth":["webhooks:write"]}],"requestBody":{"description":"Webhook configuration","required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string","minLength":1,"maxLength":120},"triggers":{"type":"array","items":{"type":"string","minLength":1,"maxLength":128},"minItems":1,"maxItems":50},"endpoint":{"type":"string","maxLength":2048,"format":"uri"},"customHeaders":{"type":"array","items":{"type":"object","properties":{"name":{"type":"string","minLength":1,"maxLength":128},"value":{"type":"string","maxLength":4096}},"required":["name","value"]},"maxItems":20},"signingEnabled":{"type":"boolean"}},"required":["name","triggers","endpoint"]}}}},"responses":{"201":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","enum":[true]},"data":{"$ref":"#/components/schemas/WebhookCreateResult"},"timestamp":{"type":"string","format":"date-time"},"requestId":{"type":"string"},"message":{"type":"string"}},"required":["success","data","timestamp"]},"example":{"success":true,"data":{"webhook":{"id":"53cbd165-50da-4525-8e31-fad24eaddee2","organizationId":"8a0d4fa0-f4f4-4c06-81ac-dbdf5e1e19c1","name":"string","trigger":"string","endpoint":"https://example.com","status":"active","apiVersion":"string","customHeaders":[{"name":"string","valueHint":"string"}],"signing":{"enabled":true,"secretHint":"string"},"consecutiveFailures":1,"lastSuccessAt":"2026-08-19T09:41:12.004Z","lastFailureAt":"2026-08-19T09:41:12.004Z","disabledReason":"string","createdAt":"2026-08-19T09:41:12.004Z","updatedAt":"2026-08-19T09:41:12.004Z"},"signingSecret":"string"},"timestamp":"2026-08-19T09:41:12.004Z","requestId":"req_01J5X8ZC3K4T7Q9M2W6B0N1V4H","message":"string"}}}},"400":{"description":"Validation error","content":{"application/json":{"example":{"success":false,"error":"Bad request","code":"BAD_REQUEST","timestamp":"2026-08-19T09:41:12.004Z","requestId":"req_01J5X8ZC3K4T7Q9M2W6B0N1V4H"},"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Unauthorized","content":{"application/json":{"example":{"success":false,"error":"Unauthorized","code":"UNAUTHORIZED","timestamp":"2026-08-19T09:41:12.004Z","requestId":"req_01J5X8ZC3K4T7Q9M2W6B0N1V4H"},"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Forbidden — missing scope","content":{"application/json":{"example":{"success":false,"error":"Forbidden","code":"FORBIDDEN","timestamp":"2026-08-19T09:41:12.004Z","requestId":"req_01J5X8ZC3K4T7Q9M2W6B0N1V4H"},"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not found","content":{"application/json":{"example":{"success":false,"error":"Resource not found","code":"NOT_FOUND","timestamp":"2026-08-19T09:41:12.004Z","requestId":"req_01J5X8ZC3K4T7Q9M2W6B0N1V4H"},"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limit exceeded","content":{"application/json":{"example":{"success":false,"error":"Too many requests","code":"TOO_MANY_REQUESTS","timestamp":"2026-08-19T09:41:12.004Z","requestId":"req_01J5X8ZC3K4T7Q9M2W6B0N1V4H"},"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/webhooks/triggers":{"get":{"operationId":"getWebhooksTriggers","tags":["Webhooks"],"summary":"List available webhook triggers, annotated with the org’s entitlement","description":"The selectable event catalogue (status != removed). Each entry carries `tier` (core | premium), `status`, and `entitled` — whether the org may currently subscribe to it given its plan + enabled products. Use the `trigger` value when creating a webhook.","security":[{"bearerAuth":["webhooks:read"]}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","enum":[true]},"data":{"type":"array","items":{"$ref":"#/components/schemas/WebhookTrigger"}},"timestamp":{"type":"string","format":"date-time"},"requestId":{"type":"string"},"message":{"type":"string"}},"required":["success","data","timestamp"]},"example":{"success":true,"data":[{"trigger":"string","description":"string","tier":"core","status":"active","entitled":true}],"timestamp":"2026-08-19T09:41:12.004Z","requestId":"req_01J5X8ZC3K4T7Q9M2W6B0N1V4H","message":"string"}}}},"400":{"description":"Validation error","content":{"application/json":{"example":{"success":false,"error":"Bad request","code":"BAD_REQUEST","timestamp":"2026-08-19T09:41:12.004Z","requestId":"req_01J5X8ZC3K4T7Q9M2W6B0N1V4H"},"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Unauthorized","content":{"application/json":{"example":{"success":false,"error":"Unauthorized","code":"UNAUTHORIZED","timestamp":"2026-08-19T09:41:12.004Z","requestId":"req_01J5X8ZC3K4T7Q9M2W6B0N1V4H"},"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Forbidden — missing scope","content":{"application/json":{"example":{"success":false,"error":"Forbidden","code":"FORBIDDEN","timestamp":"2026-08-19T09:41:12.004Z","requestId":"req_01J5X8ZC3K4T7Q9M2W6B0N1V4H"},"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not found","content":{"application/json":{"example":{"success":false,"error":"Resource not found","code":"NOT_FOUND","timestamp":"2026-08-19T09:41:12.004Z","requestId":"req_01J5X8ZC3K4T7Q9M2W6B0N1V4H"},"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limit exceeded","content":{"application/json":{"example":{"success":false,"error":"Too many requests","code":"TOO_MANY_REQUESTS","timestamp":"2026-08-19T09:41:12.004Z","requestId":"req_01J5X8ZC3K4T7Q9M2W6B0N1V4H"},"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/webhooks/{id}":{"get":{"operationId":"getWebhooksById","tags":["Webhooks"],"summary":"Get a webhook by id","security":[{"bearerAuth":["webhooks:read"]}],"parameters":[{"schema":{"type":"string","format":"uuid"},"required":true,"name":"id","in":"path"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","enum":[true]},"data":{"$ref":"#/components/schemas/Webhook"},"timestamp":{"type":"string","format":"date-time"},"requestId":{"type":"string"},"message":{"type":"string"}},"required":["success","data","timestamp"]},"example":{"success":true,"data":{"id":"f5005b73-208f-42e3-829b-56a01e89642c","organizationId":"d532b472-0ed2-4c50-87a9-66a99caca257","name":"string","trigger":"string","endpoint":"https://example.com","status":"active","apiVersion":"string","customHeaders":[{"name":"string","valueHint":"string"}],"signing":{"enabled":true,"secretHint":"string"},"consecutiveFailures":1,"lastSuccessAt":"2026-08-19T09:41:12.004Z","lastFailureAt":"2026-08-19T09:41:12.004Z","disabledReason":"string","createdAt":"2026-08-19T09:41:12.004Z","updatedAt":"2026-08-19T09:41:12.004Z"},"timestamp":"2026-08-19T09:41:12.004Z","requestId":"req_01J5X8ZC3K4T7Q9M2W6B0N1V4H","message":"string"}}}},"400":{"description":"Validation error","content":{"application/json":{"example":{"success":false,"error":"Bad request","code":"BAD_REQUEST","timestamp":"2026-08-19T09:41:12.004Z","requestId":"req_01J5X8ZC3K4T7Q9M2W6B0N1V4H"},"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Unauthorized","content":{"application/json":{"example":{"success":false,"error":"Unauthorized","code":"UNAUTHORIZED","timestamp":"2026-08-19T09:41:12.004Z","requestId":"req_01J5X8ZC3K4T7Q9M2W6B0N1V4H"},"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Forbidden — missing scope","content":{"application/json":{"example":{"success":false,"error":"Forbidden","code":"FORBIDDEN","timestamp":"2026-08-19T09:41:12.004Z","requestId":"req_01J5X8ZC3K4T7Q9M2W6B0N1V4H"},"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not found","content":{"application/json":{"example":{"success":false,"error":"Resource not found","code":"NOT_FOUND","timestamp":"2026-08-19T09:41:12.004Z","requestId":"req_01J5X8ZC3K4T7Q9M2W6B0N1V4H"},"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limit exceeded","content":{"application/json":{"example":{"success":false,"error":"Too many requests","code":"TOO_MANY_REQUESTS","timestamp":"2026-08-19T09:41:12.004Z","requestId":"req_01J5X8ZC3K4T7Q9M2W6B0N1V4H"},"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}},"patch":{"operationId":"patchWebhooksById","tags":["Webhooks"],"summary":"Update a webhook","description":"Patch name / trigger / endpoint / status (active|disabled) / customHeaders. A changed trigger is re-validated against the org’s available set; a changed endpoint is re-validated by the SSRF allow-list. Re-activating a suspended webhook clears its auto-disable bookkeeping.","security":[{"bearerAuth":["webhooks:write"]}],"parameters":[{"schema":{"type":"string","format":"uuid"},"required":true,"name":"id","in":"path"}],"requestBody":{"description":"Partial webhook update","required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string","minLength":1,"maxLength":120},"triggers":{"type":"array","items":{"type":"string","minLength":1,"maxLength":128},"minItems":1,"maxItems":50},"endpoint":{"type":"string","maxLength":2048,"format":"uri"},"status":{"type":"string","enum":["active","disabled"]},"customHeaders":{"type":"array","items":{"type":"object","properties":{"name":{"type":"string","minLength":1,"maxLength":128},"value":{"type":"string","maxLength":4096}},"required":["name","value"]},"maxItems":20}}}}}},"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","enum":[true]},"data":{"$ref":"#/components/schemas/Webhook"},"timestamp":{"type":"string","format":"date-time"},"requestId":{"type":"string"},"message":{"type":"string"}},"required":["success","data","timestamp"]},"example":{"success":true,"data":{"id":"537208a1-ff83-4899-8629-3a6e8ce6f4de","organizationId":"46cbbdfc-70bc-46da-8117-f79b47bacf4d","name":"string","trigger":"string","endpoint":"https://example.com","status":"active","apiVersion":"string","customHeaders":[{"name":"string","valueHint":"string"}],"signing":{"enabled":true,"secretHint":"string"},"consecutiveFailures":1,"lastSuccessAt":"2026-08-19T09:41:12.004Z","lastFailureAt":"2026-08-19T09:41:12.004Z","disabledReason":"string","createdAt":"2026-08-19T09:41:12.004Z","updatedAt":"2026-08-19T09:41:12.004Z"},"timestamp":"2026-08-19T09:41:12.004Z","requestId":"req_01J5X8ZC3K4T7Q9M2W6B0N1V4H","message":"string"}}}},"400":{"description":"Validation error","content":{"application/json":{"example":{"success":false,"error":"Bad request","code":"BAD_REQUEST","timestamp":"2026-08-19T09:41:12.004Z","requestId":"req_01J5X8ZC3K4T7Q9M2W6B0N1V4H"},"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Unauthorized","content":{"application/json":{"example":{"success":false,"error":"Unauthorized","code":"UNAUTHORIZED","timestamp":"2026-08-19T09:41:12.004Z","requestId":"req_01J5X8ZC3K4T7Q9M2W6B0N1V4H"},"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Forbidden — missing scope","content":{"application/json":{"example":{"success":false,"error":"Forbidden","code":"FORBIDDEN","timestamp":"2026-08-19T09:41:12.004Z","requestId":"req_01J5X8ZC3K4T7Q9M2W6B0N1V4H"},"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not found","content":{"application/json":{"example":{"success":false,"error":"Resource not found","code":"NOT_FOUND","timestamp":"2026-08-19T09:41:12.004Z","requestId":"req_01J5X8ZC3K4T7Q9M2W6B0N1V4H"},"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limit exceeded","content":{"application/json":{"example":{"success":false,"error":"Too many requests","code":"TOO_MANY_REQUESTS","timestamp":"2026-08-19T09:41:12.004Z","requestId":"req_01J5X8ZC3K4T7Q9M2W6B0N1V4H"},"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}},"delete":{"operationId":"deleteWebhooksById","tags":["Webhooks"],"summary":"Delete a webhook","security":[{"bearerAuth":["webhooks:write"]}],"parameters":[{"schema":{"type":"string","format":"uuid"},"required":true,"name":"id","in":"path"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","enum":[true]},"data":{"type":"object","properties":{"deleted":{"type":"boolean","enum":[true]}},"required":["deleted"]},"timestamp":{"type":"string","format":"date-time"},"requestId":{"type":"string"},"message":{"type":"string"}},"required":["success","data","timestamp"]},"example":{"success":true,"data":{"deleted":true},"timestamp":"2026-08-19T09:41:12.004Z","requestId":"req_01J5X8ZC3K4T7Q9M2W6B0N1V4H","message":"string"}}}},"400":{"description":"Validation error","content":{"application/json":{"example":{"success":false,"error":"Bad request","code":"BAD_REQUEST","timestamp":"2026-08-19T09:41:12.004Z","requestId":"req_01J5X8ZC3K4T7Q9M2W6B0N1V4H"},"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Unauthorized","content":{"application/json":{"example":{"success":false,"error":"Unauthorized","code":"UNAUTHORIZED","timestamp":"2026-08-19T09:41:12.004Z","requestId":"req_01J5X8ZC3K4T7Q9M2W6B0N1V4H"},"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Forbidden — missing scope","content":{"application/json":{"example":{"success":false,"error":"Forbidden","code":"FORBIDDEN","timestamp":"2026-08-19T09:41:12.004Z","requestId":"req_01J5X8ZC3K4T7Q9M2W6B0N1V4H"},"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not found","content":{"application/json":{"example":{"success":false,"error":"Resource not found","code":"NOT_FOUND","timestamp":"2026-08-19T09:41:12.004Z","requestId":"req_01J5X8ZC3K4T7Q9M2W6B0N1V4H"},"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limit exceeded","content":{"application/json":{"example":{"success":false,"error":"Too many requests","code":"TOO_MANY_REQUESTS","timestamp":"2026-08-19T09:41:12.004Z","requestId":"req_01J5X8ZC3K4T7Q9M2W6B0N1V4H"},"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/webhooks/{id}/deliveries":{"get":{"operationId":"getWebhooksByIdDeliveries","tags":["Webhooks"],"summary":"List a webhook’s deliveries (cursor-paginated)","description":"Cursor-paginated read of the delivery log for one webhook, newest first. Pass `?cursor=<opaque>&limit=<n>` to advance; the response carries `cursor.nextCursor` (null on the last page) plus `cursor.hasMore`.","security":[{"bearerAuth":["webhooks:read"]}],"parameters":[{"schema":{"type":"string","format":"uuid"},"required":true,"name":"id","in":"path"},{"schema":{"type":"string"},"required":false,"name":"cursor","in":"query"},{"schema":{"type":"integer","minimum":1,"maximum":100},"required":false,"name":"limit","in":"query"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","enum":[true]},"data":{"type":"array","items":{"$ref":"#/components/schemas/WebhookDelivery"}},"timestamp":{"type":"string","format":"date-time"},"requestId":{"type":"string"},"message":{"type":"string"},"cursor":{"$ref":"#/components/schemas/CursorMeta"}},"required":["success","data","timestamp","cursor"]},"example":{"success":true,"data":[{"id":"dbbb7e62-4827-4120-89e0-9a19b9929ba7","webhookId":"b9b6a755-b189-4df5-8158-1a42b3b15c32","trigger":"string","apiVersion":"string","status":"pending","payload":{},"responseStatus":1,"errorMessage":"string","durationMs":1,"sentAt":"2026-08-19T09:41:12.004Z","isReplay":true,"replayOfDeliveryId":"4f20ca24-b69e-49d2-8c15-0403cc155705","createdAt":"2026-08-19T09:41:12.004Z"}],"timestamp":"2026-08-19T09:41:12.004Z","requestId":"req_01J5X8ZC3K4T7Q9M2W6B0N1V4H","message":"string","cursor":{"nextCursor":"string","hasMore":true,"limit":1}}}}},"400":{"description":"Validation error","content":{"application/json":{"example":{"success":false,"error":"Bad request","code":"BAD_REQUEST","timestamp":"2026-08-19T09:41:12.004Z","requestId":"req_01J5X8ZC3K4T7Q9M2W6B0N1V4H"},"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Unauthorized","content":{"application/json":{"example":{"success":false,"error":"Unauthorized","code":"UNAUTHORIZED","timestamp":"2026-08-19T09:41:12.004Z","requestId":"req_01J5X8ZC3K4T7Q9M2W6B0N1V4H"},"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Forbidden — missing scope","content":{"application/json":{"example":{"success":false,"error":"Forbidden","code":"FORBIDDEN","timestamp":"2026-08-19T09:41:12.004Z","requestId":"req_01J5X8ZC3K4T7Q9M2W6B0N1V4H"},"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not found","content":{"application/json":{"example":{"success":false,"error":"Resource not found","code":"NOT_FOUND","timestamp":"2026-08-19T09:41:12.004Z","requestId":"req_01J5X8ZC3K4T7Q9M2W6B0N1V4H"},"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limit exceeded","content":{"application/json":{"example":{"success":false,"error":"Too many requests","code":"TOO_MANY_REQUESTS","timestamp":"2026-08-19T09:41:12.004Z","requestId":"req_01J5X8ZC3K4T7Q9M2W6B0N1V4H"},"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}}},"webhooks":{}}