{"openapi":"3.1.0","info":{"title":"V77 Trust API","version":"2026-11-01","summary":"EU AI Act compliance as an API: inventory, risk classification, controls, evidence, incidents, testing and audit trail.","description":"REST API for V77 Trust. All requests use HTTPS and an API key: `Authorization: Bearer v77_…`. Admins create keys in Settings → API keys; each key has a role (auditor = read-only, reviewer, ai_owner, admin).\n\nErrors share one format with a stable `code` and a `request_id`. Lists are cursor-paginated. POST requests accept an `Idempotency-Key` header so retries never act twice. Rate limit: 120 requests per minute per key.\n\nGuides and examples: https://developer.v77trust.com","contact":{"name":"V77 Trust developer support","email":"contact@v77trust.com","url":"https://developer.v77trust.com"},"termsOfService":"https://v77trust.com/terms"},"externalDocs":{"description":"Developer guides","url":"https://developer.v77trust.com"},"servers":[{"url":"https://v77trust.com","description":"Production (EU data residency)"}],"security":[{"bearer":[]}],"tags":[{"name":"Account","description":"Check your key and workspace."},{"name":"AI systems","description":"Your AI inventory (EU AI Act Art. 49 / Art. 26)."},{"name":"Classification","description":"Risk tier and obligations under the EU AI Act."},{"name":"Controls & evidence","description":"Controls crosswalked to the AI Act, NIST AI RMF, ISO 42001, GDPR, DORA; tamper-evident evidence."},{"name":"Findings & incidents","description":"Issues and serious-incident reporting (Art. 73, DORA, GDPR Art. 33)."},{"name":"Testing","description":"Adversarial red-team testing (Art. 15, OWASP LLM Top 10)."},{"name":"Release gate","description":"Block deployments that aren't ready."},{"name":"Audit trail","description":"Hash-chained record for auditors and regulators."},{"name":"Webhooks","description":"Get notified when things change."}],"components":{"securitySchemes":{"bearer":{"type":"http","scheme":"bearer","bearerFormat":"v77_<key>","description":"API key from Settings → API keys."}},"parameters":{"IdempotencyKey":{"name":"Idempotency-Key","in":"header","required":false,"description":"Unique value (e.g. a UUID) per operation. Retrying with the same key returns the original response for 24 hours.","schema":{"type":"string","maxLength":255}}},"headers":{"RequestId":{"description":"Unique id for this request; quote it to support.","schema":{"type":"string"}},"RateLimitRemaining":{"description":"Requests left in the current minute.","schema":{"type":"integer"}}},"schemas":{"Error":{"type":"object","properties":{"error":{"type":"object","properties":{"type":{"type":"string","enum":["authentication_error","permission_error","invalid_request_error","not_found_error","conflict_error","rate_limit_error","plan_limit_error","api_error"]},"code":{"type":"string","description":"Stable, machine-readable code, e.g. validation_failed, evidence_required."},"message":{"type":"string","description":"Human-readable explanation."},"param":{"type":"string","description":"The request field the error is about, when there is one."},"request_id":{"type":"string","description":"Quote this when contacting support."},"doc_url":{"type":"string"}},"required":["type","code","message","request_id"]}},"required":["error"],"example":{"error":{"type":"invalid_request_error","code":"validation_failed","message":"name: String must contain at least 1 character(s)","param":"name","request_id":"req_5f0c1e…","doc_url":"https://developer.v77trust.com/errors#validation_failed"}}},"AiSystem":{"type":"object","properties":{"object":{"const":"ai_system"},"id":{"type":"string"},"name":{"type":"string"},"description":{"type":"string"},"intendedPurpose":{"type":"string","description":"Intended purpose (EU AI Act Art. 3(12)); the risk tier depends on it."},"roleInValueChain":{"type":"string","enum":["provider","deployer","importer","distributor"]},"sector":{"type":"string","description":"Sector id, e.g. banking_credit, insurance, employment_hr, healthcare_medtech."},"riskTier":{"type":["string","null"],"enum":["prohibited","high_risk","limited","minimal","gpai"],"description":"null until classified."},"gpai":{"type":"boolean","description":"General-purpose AI model (Chapter V)."},"classificationNotes":{"type":"string"},"lifecycleStatus":{"type":"string","enum":["discovered","pilot","production","retired"]},"businessUnit":{"type":["string","null"]},"vendor":{"type":["string","null"]},"version":{"type":["string","null"]},"euDatabaseId":{"type":["string","null"],"description":"EU database registration id (Art. 49), when registered."},"lastReviewedAt":{"type":["string","null"],"format":"date-time"},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}}},"ClassificationQuestion":{"type":"object","properties":{"object":{"const":"classification_question"},"id":{"type":"string"},"section":{"type":"string","enum":["prohibited","high_risk","limited","gpai","context"]},"prompt":{"type":"string"},"help":{"type":"string"},"weight":{"type":"string","enum":["hard","soft"]}}},"Classification":{"type":"object","properties":{"object":{"const":"classification"},"systemId":{"type":"string"},"riskTier":{"type":"string","enum":["prohibited","high_risk","limited","minimal","gpai"]},"gpai":{"type":"boolean"},"systemicRisk":{"type":"boolean"},"art6_3ExemptionClaimed":{"type":"boolean","description":"Art. 6(3) derogation from high-risk applies."},"art25ProviderEscalation":{"type":"boolean","description":"Art. 25: you become the provider (e.g. substantial modification)."},"reasons":{"type":"array","items":{"type":"string"}},"answers":{"type":"object","additionalProperties":{"type":"string","enum":["yes","no","na"]}},"assessmentId":{"type":["string","null"],"description":"Assessment opened with the applicable controls."},"dryRun":{"type":"boolean"},"disclaimer":{"type":"string"}}},"Obligation":{"type":"object","properties":{"object":{"const":"obligation"},"id":{"type":"string"},"title":{"type":"string"},"article":{"type":"string","description":"e.g. Art. 9"},"detail":{"type":"string"},"appliesTo":{"type":"string"}}},"ControlReferences":{"type":"object","properties":{"euAiAct":{"type":["string","null"]},"nistAiRmf":{"type":["string","null"]},"iso42001":{"type":["string","null"]},"gdpr":{"type":["string","null"]},"dora":{"type":["string","null"]},"iso27001":{"type":["string","null"]}}},"Control":{"type":"object","properties":{"object":{"const":"control"},"id":{"type":"string"},"code":{"type":"string","description":"e.g. V77-DOC-01"},"title":{"type":"string"},"description":{"type":"string"},"area":{"type":"string"},"appliesTo":{"type":"array","items":{"type":"string","enum":["prohibited","high_risk","limited","minimal","gpai"]}},"references":{"$ref":"#/components/schemas/ControlReferences"}}},"SystemControl":{"type":"object","properties":{"object":{"const":"system_control"},"controlId":{"type":"string"},"code":{"type":"string"},"title":{"type":"string"},"area":{"type":"string"},"status":{"type":"string","enum":["not_started","in_progress","implemented","not_applicable","waived"]},"notes":{"type":"string"},"references":{"$ref":"#/components/schemas/ControlReferences"}}},"Evidence":{"type":"object","properties":{"object":{"const":"evidence"},"id":{"type":"string"},"systemId":{"type":["string","null"]},"controlId":{"type":["string","null"]},"title":{"type":"string"},"filename":{"type":"string"},"contentType":{"type":"string"},"sha256":{"type":"string","description":"SHA-256 of the file."},"prevSha256":{"type":["string","null"],"description":"Hash of the previous evidence item: a tamper-evident chain."},"createdAt":{"type":"string","format":"date-time"}}},"Finding":{"type":"object","properties":{"object":{"const":"finding"},"id":{"type":"string"},"systemId":{"type":"string"},"assessmentId":{"type":["string","null"]},"title":{"type":"string"},"description":{"type":"string"},"severity":{"type":"string","enum":["low","medium","high","critical"]},"status":{"type":"string","enum":["open","in_progress","resolved","accepted"]},"frameworkRef":{"type":["string","null"]},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}}},"ReportingDeadline":{"type":"object","properties":{"regime":{"type":"string","enum":["ai_act","dora","gdpr"]},"step":{"type":"string"},"label":{"type":"string"},"article":{"type":"string"},"dueAt":{"type":["string","null"],"format":"date-time"},"doneAt":{"type":["string","null"],"format":"date-time"},"state":{"type":"string","enum":["done","overdue","due_soon","open","waiting"]}}},"Incident":{"type":"object","properties":{"object":{"const":"incident"},"id":{"type":"string"},"systemId":{"type":["string","null"]},"title":{"type":"string"},"description":{"type":"string"},"severity":{"type":"string","enum":["low","medium","high","critical"]},"status":{"type":"string","enum":["open","investigating","mitigated","closed"]},"seriousIncident":{"type":"boolean","description":"Serious incident under EU AI Act Art. 3(49) / Art. 73."},"euArticleRef":{"type":"string","enum":["Art. 73(2)","Art. 73(3)","Art. 73(4)"]},"awareAt":{"type":["string","null"],"description":"When you became aware; reporting clocks start here.","format":"date-time"},"occurredAt":{"type":["string","null"],"format":"date-time"},"impactSummary":{"type":"string"},"rootCause":{"type":"string"},"correctiveActions":{"type":"string"},"authorityNotified":{"type":"boolean"},"authorityNotifiedAt":{"type":["string","null"],"format":"date-time"},"doraMajor":{"type":"boolean"},"gdprBreach":{"type":"boolean"},"gdprNotifiedAt":{"type":["string","null"],"format":"date-time"},"reportingDeadlines":{"type":"array","items":{"$ref":"#/components/schemas/ReportingDeadline"}},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}}},"RedteamResult":{"type":"object","properties":{"scenarioId":{"type":"string"},"category":{"type":"string","enum":["jailbreak","prompt_injection","exfiltration","harmful","tool_abuse"]},"name":{"type":"string"},"verdict":{"type":"string","enum":["pass","fail","review"],"description":"review = the automated screen couldn't decide; a person should read the reply."},"reason":{"type":"string"},"prompt":{"type":"string"},"response":{"type":"string"},"reviewedBy":{"type":["object","null"],"properties":{"name":{"type":"string"},"at":{"type":"string","format":"date-time"},"passed":{"type":"boolean"}}},"owaspLlmRef":{"type":["string","null"]},"euAiActRef":{"type":["string","null"]}}},"RedteamRun":{"type":"object","properties":{"object":{"const":"redteam_run"},"id":{"type":"string"},"systemId":{"type":"string"},"provider":{"type":"string"},"summary":{"type":"object","properties":{"total":{"type":"integer"},"passed":{"type":"integer"},"failed":{"type":"integer"},"needsReview":{"type":"integer"}}},"results":{"type":"array","items":{"$ref":"#/components/schemas/RedteamResult"},"description":"Included when you fetch a single run."},"createdAt":{"type":"string","format":"date-time"}}},"ComplianceGate":{"type":"object","properties":{"object":{"const":"compliance_gate"},"passed":{"type":"boolean"},"status":{"type":"string","enum":["pass","blocked"]},"systemId":{"type":"string"},"systemName":{"type":"string"},"riskTier":{"type":["string","null"],"enum":["prohibited","high_risk","limited","minimal","gpai"]},"readinessPercent":{"type":"integer"},"blockers":{"type":"array","items":{"type":"string"}},"warnings":{"type":"array","items":{"type":"string"}},"evaluatedAt":{"type":"string","format":"date-time"}}},"AuditEvent":{"type":"object","properties":{"object":{"const":"audit_event"},"id":{"type":"string"},"action":{"type":"string","description":"e.g. system.classified, evidence.upload, control.updated"},"entityType":{"type":"string"},"entityId":{"type":"string"},"actor":{"type":"object","properties":{"type":{"type":"string","enum":["user","api_key","system"]},"email":{"type":"string"},"id":{"type":"string"}}},"detail":{"type":"object"},"prevSha256":{"type":["string","null"]},"sha256":{"type":"string"},"createdAt":{"type":"string","format":"date-time"}}},"WebhookEndpoint":{"type":"object","properties":{"object":{"const":"webhook_endpoint"},"id":{"type":"string"},"url":{"type":"string"},"events":{"type":"array","items":{"type":"string"}},"active":{"type":"boolean"},"createdAt":{"type":"string","format":"date-time"},"secret":{"type":"string","description":"Only in the create response. Store it to verify signatures."}}}}},"paths":{"/api/v1/me":{"get":{"tags":["Account"],"summary":"Check your API key","description":"Returns the workspace and key behind the request. Use it to confirm a key works.","x-v77-min-role":"auditor","responses":{"200":{"description":"Success.","headers":{"X-Request-Id":{"$ref":"#/components/headers/RequestId"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/RateLimitRemaining"}},"content":{"application/json":{"schema":{"type":"object"},"example":{"object":"api_context","workspace":{"id":"…","name":"EuroBank AG"},"apiKey":{"id":"…","name":"CI pipeline","prefix":"v77_Ab12Cd34","role":"ai_owner"},"apiVersion":"2026-11-01"}}}},"401":{"description":"Missing or invalid API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"The API key's role isn't allowed to do this.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited (120 requests/minute per key). See Retry-After.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/systems":{"get":{"tags":["AI systems"],"summary":"List AI systems","description":"Your AI inventory, newest first.","x-v77-min-role":"auditor","parameters":[{"name":"limit","in":"query","required":false,"description":"Items per page, 1–100.","schema":{"type":"integer","minimum":1,"maximum":100,"default":25}},{"name":"cursor","in":"query","required":false,"description":"next_cursor from the previous page.","schema":{"type":"string"}},{"name":"riskTier","in":"query","required":false,"description":"Filter by tier, or unclassified.","schema":{"type":"string","enum":["prohibited","high_risk","limited","minimal","gpai","unclassified"]}},{"name":"lifecycleStatus","in":"query","required":false,"description":"Filter by stage.","schema":{"type":"string","enum":["discovered","pilot","production","retired"]}},{"name":"sector","in":"query","required":false,"description":"Filter by sector id.","schema":{"type":"string"}},{"name":"q","in":"query","required":false,"description":"Search name and intended purpose.","schema":{"type":"string"}}],"responses":{"200":{"description":"Success.","headers":{"X-Request-Id":{"$ref":"#/components/headers/RequestId"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/RateLimitRemaining"}},"content":{"application/json":{"schema":{"type":"object","properties":{"object":{"const":"list"},"data":{"type":"array","items":{"$ref":"#/components/schemas/AiSystem"}},"has_more":{"type":"boolean"},"next_cursor":{"type":["string","null"],"description":"Pass as cursor to get the next page."}},"required":["object","data","has_more","next_cursor"]}}}},"400":{"description":"Invalid request (validation_failed, invalid_parameter, invalid_json…).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing or invalid API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"The API key's role isn't allowed to do this.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited (120 requests/minute per key). See Retry-After.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"post":{"tags":["AI systems"],"summary":"Add an AI system","description":"Adds a system to the inventory. Classify it next to set its risk tier.","x-v77-min-role":"ai_owner","parameters":[{"$ref":"#/components/parameters/IdempotencyKey"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["name"],"properties":{"name":{"type":"string"},"description":{"type":"string"},"intendedPurpose":{"type":"string"},"roleInValueChain":{"type":"string","enum":["provider","deployer","importer","distributor"]},"sector":{"type":"string"},"lifecycleStatus":{"type":"string","enum":["discovered","pilot","production","retired"]},"businessUnit":{"type":"string"},"vendor":{"type":"string"},"version":{"type":"string"},"euDatabaseId":{"type":"string"}}},"example":{"name":"Retail credit scoring","intendedPurpose":"Assess creditworthiness of consumers applying for loans","roleInValueChain":"provider","sector":"banking_credit","lifecycleStatus":"production","businessUnit":"Retail Banking","vendor":"In-house (XGBoost)"}}}},"responses":{"201":{"description":"Success.","headers":{"X-Request-Id":{"$ref":"#/components/headers/RequestId"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/RateLimitRemaining"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AiSystem"}}}},"400":{"description":"Invalid request (validation_failed, invalid_parameter, invalid_json…).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing or invalid API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"Your plan's limit has been reached.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"The API key's role isn't allowed to do this.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited (120 requests/minute per key). See Retry-After.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/systems/{id}":{"get":{"tags":["AI systems"],"summary":"Get an AI system","x-v77-min-role":"auditor","parameters":[{"name":"id","in":"path","required":true,"description":"AI system id.","schema":{"type":"string"}}],"responses":{"200":{"description":"Success.","headers":{"X-Request-Id":{"$ref":"#/components/headers/RequestId"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/RateLimitRemaining"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AiSystem"}}}},"401":{"description":"Missing or invalid API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"The API key's role isn't allowed to do this.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found in this workspace.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited (120 requests/minute per key). See Retry-After.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"patch":{"tags":["AI systems"],"summary":"Update an AI system","description":"Only the fields you send change. The risk tier changes only through classification. Send markReviewed: true to record a periodic review.","x-v77-min-role":"ai_owner","parameters":[{"name":"id","in":"path","required":true,"description":"AI system id.","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string"},"description":{"type":"string"},"intendedPurpose":{"type":"string"},"roleInValueChain":{"type":"string","enum":["provider","deployer","importer","distributor"]},"sector":{"type":"string"},"lifecycleStatus":{"type":"string","enum":["discovered","pilot","production","retired"]},"businessUnit":{"type":"string"},"vendor":{"type":"string"},"version":{"type":"string"},"euDatabaseId":{"type":"string"},"markReviewed":{"type":"boolean"}},"additionalProperties":false}}}},"responses":{"200":{"description":"Success.","headers":{"X-Request-Id":{"$ref":"#/components/headers/RequestId"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/RateLimitRemaining"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AiSystem"}}}},"400":{"description":"Invalid request (validation_failed, invalid_parameter, invalid_json…).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing or invalid API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"The API key's role isn't allowed to do this.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found in this workspace.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited (120 requests/minute per key). See Retry-After.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/classification/questions":{"get":{"tags":["Classification"],"summary":"List classification questions","description":"The EU AI Act screening questionnaire (prohibited practices, Annex I/III high-risk, Art. 50 transparency, GPAI).","x-v77-min-role":"auditor","responses":{"200":{"description":"Success.","headers":{"X-Request-Id":{"$ref":"#/components/headers/RequestId"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/RateLimitRemaining"}},"content":{"application/json":{"schema":{"type":"object","properties":{"object":{"const":"list"},"data":{"type":"array","items":{"$ref":"#/components/schemas/ClassificationQuestion"}},"has_more":{"type":"boolean"},"next_cursor":{"type":["string","null"],"description":"Pass as cursor to get the next page."}},"required":["object","data","has_more","next_cursor"]}}}},"401":{"description":"Missing or invalid API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"The API key's role isn't allowed to do this.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited (120 requests/minute per key). See Retry-After.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/systems/{id}/classification":{"get":{"tags":["Classification"],"summary":"Get a system's classification","x-v77-min-role":"auditor","parameters":[{"name":"id","in":"path","required":true,"description":"AI system id.","schema":{"type":"string"}}],"responses":{"200":{"description":"Success.","headers":{"X-Request-Id":{"$ref":"#/components/headers/RequestId"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/RateLimitRemaining"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Classification"}}}},"401":{"description":"Missing or invalid API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"The API key's role isn't allowed to do this.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found in this workspace.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited (120 requests/minute per key). See Retry-After.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"post":{"tags":["Classification"],"summary":"Classify a system","description":"Answers each question id with yes, no or na (unanswered = no). Stores the tier and opens an assessment with the controls that apply. Use dryRun to preview without saving.","x-v77-min-role":"ai_owner","parameters":[{"name":"id","in":"path","required":true,"description":"AI system id.","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["answers"],"properties":{"answers":{"type":"object","additionalProperties":{"type":"string","enum":["yes","no","na"]}},"createAssessment":{"type":"boolean","default":true},"dryRun":{"type":"boolean","default":false}}},"example":{"answers":{"hr_annex_iii_credit":"yes","lim_interaction":"no"}}}}},"responses":{"200":{"description":"Success.","headers":{"X-Request-Id":{"$ref":"#/components/headers/RequestId"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/RateLimitRemaining"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Classification"},"example":{"object":"classification","riskTier":"high_risk","gpai":false,"reasons":["High-risk Annex III indicator (hr_annex_iii_credit)."],"assessmentId":"…"}}}},"400":{"description":"Invalid request (validation_failed, invalid_parameter, invalid_json…).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing or invalid API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"Your plan's limit has been reached.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"The API key's role isn't allowed to do this.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found in this workspace.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited (120 requests/minute per key). See Retry-After.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/systems/{id}/obligations":{"get":{"tags":["Classification"],"summary":"List a system's obligations","description":"EU AI Act obligations for the system's tier and your role in the value chain (provider, deployer…).","x-v77-min-role":"auditor","parameters":[{"name":"id","in":"path","required":true,"description":"AI system id.","schema":{"type":"string"}}],"responses":{"200":{"description":"Success.","headers":{"X-Request-Id":{"$ref":"#/components/headers/RequestId"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/RateLimitRemaining"}},"content":{"application/json":{"schema":{"type":"object","properties":{"object":{"const":"list"},"data":{"type":"array","items":{"$ref":"#/components/schemas/Obligation"}},"has_more":{"type":"boolean"},"next_cursor":{"type":["string","null"],"description":"Pass as cursor to get the next page."}},"required":["object","data","has_more","next_cursor"]}}}},"401":{"description":"Missing or invalid API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"The API key's role isn't allowed to do this.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found in this workspace.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"Conflict (state doesn't allow this, or Idempotency-Key reused).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited (120 requests/minute per key). See Retry-After.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/controls":{"get":{"tags":["Controls & evidence"],"summary":"List the control library","description":"Controls with their crosswalk to the EU AI Act, NIST AI RMF, ISO/IEC 42001, GDPR, DORA and ISO/IEC 27001.","x-v77-min-role":"auditor","parameters":[{"name":"riskTier","in":"query","required":false,"description":"Only controls that apply to this tier.","schema":{"type":"string","enum":["prohibited","high_risk","limited","minimal","gpai"]}}],"responses":{"200":{"description":"Success.","headers":{"X-Request-Id":{"$ref":"#/components/headers/RequestId"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/RateLimitRemaining"}},"content":{"application/json":{"schema":{"type":"object","properties":{"object":{"const":"list"},"data":{"type":"array","items":{"$ref":"#/components/schemas/Control"}},"has_more":{"type":"boolean"},"next_cursor":{"type":["string","null"],"description":"Pass as cursor to get the next page."}},"required":["object","data","has_more","next_cursor"]}}}},"401":{"description":"Missing or invalid API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"The API key's role isn't allowed to do this.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited (120 requests/minute per key). See Retry-After.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/systems/{id}/controls":{"get":{"tags":["Controls & evidence"],"summary":"List a system's controls","description":"Controls on the system's latest assessment, with status and a readiness summary.","x-v77-min-role":"auditor","parameters":[{"name":"id","in":"path","required":true,"description":"AI system id.","schema":{"type":"string"}}],"responses":{"200":{"description":"Success.","headers":{"X-Request-Id":{"$ref":"#/components/headers/RequestId"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/RateLimitRemaining"}},"content":{"application/json":{"schema":{"type":"object","properties":{"object":{"const":"list"},"data":{"type":"array","items":{"$ref":"#/components/schemas/SystemControl"}},"has_more":{"type":"boolean"},"next_cursor":{"type":["string","null"],"description":"Pass as cursor to get the next page."}},"required":["object","data","has_more","next_cursor"]}}}},"401":{"description":"Missing or invalid API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"The API key's role isn't allowed to do this.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found in this workspace.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited (120 requests/minute per key). See Retry-After.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/systems/{id}/controls/{code}":{"patch":{"tags":["Controls & evidence"],"summary":"Update a control's status","description":"Marking a control implemented needs at least one evidence item linked to it (422 evidence_required otherwise).","x-v77-min-role":"ai_owner","parameters":[{"name":"id","in":"path","required":true,"description":"AI system id.","schema":{"type":"string"}},{"name":"code","in":"path","required":true,"description":"Control code, e.g. V77-DOC-01.","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"status":{"type":"string","enum":["not_started","in_progress","implemented","not_applicable","waived"]},"notes":{"type":"string"}},"additionalProperties":false},"example":{"status":"implemented","notes":"Risk register approved by the model risk committee."}}}},"responses":{"200":{"description":"Success.","headers":{"X-Request-Id":{"$ref":"#/components/headers/RequestId"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/RateLimitRemaining"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SystemControl"}}}},"400":{"description":"Invalid request (validation_failed, invalid_parameter, invalid_json…).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing or invalid API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"The API key's role isn't allowed to do this.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found in this workspace.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"Conflict (state doesn't allow this, or Idempotency-Key reused).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"Request understood but refused by a compliance rule.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited (120 requests/minute per key). See Retry-After.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/evidence":{"get":{"tags":["Controls & evidence"],"summary":"List evidence","x-v77-min-role":"auditor","parameters":[{"name":"limit","in":"query","required":false,"description":"Items per page, 1–100.","schema":{"type":"integer","minimum":1,"maximum":100,"default":25}},{"name":"cursor","in":"query","required":false,"description":"next_cursor from the previous page.","schema":{"type":"string"}},{"name":"systemId","in":"query","required":false,"description":"Filter by system.","schema":{"type":"string"}},{"name":"controlCode","in":"query","required":false,"description":"Filter by control code.","schema":{"type":"string"}}],"responses":{"200":{"description":"Success.","headers":{"X-Request-Id":{"$ref":"#/components/headers/RequestId"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/RateLimitRemaining"}},"content":{"application/json":{"schema":{"type":"object","properties":{"object":{"const":"list"},"data":{"type":"array","items":{"$ref":"#/components/schemas/Evidence"}},"has_more":{"type":"boolean"},"next_cursor":{"type":["string","null"],"description":"Pass as cursor to get the next page."}},"required":["object","data","has_more","next_cursor"]}}}},"400":{"description":"Invalid request (validation_failed, invalid_parameter, invalid_json…).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing or invalid API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"The API key's role isn't allowed to do this.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited (120 requests/minute per key). See Retry-After.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"post":{"tags":["Controls & evidence"],"summary":"Upload evidence","description":"multipart/form-data, up to 25 MB. The file is SHA-256 hashed and chained to the previous item.","x-v77-min-role":"ai_owner","parameters":[{"$ref":"#/components/parameters/IdempotencyKey"}],"requestBody":{"required":true,"content":{"multipart/form-data":{"schema":{"type":"object","required":["file"],"properties":{"file":{"type":"string","format":"binary"},"title":{"type":"string"},"systemId":{"type":"string"},"controlCode":{"type":"string"}}}}}},"responses":{"201":{"description":"Success.","headers":{"X-Request-Id":{"$ref":"#/components/headers/RequestId"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/RateLimitRemaining"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Evidence"}}}},"400":{"description":"Invalid request (validation_failed, invalid_parameter, invalid_json…).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing or invalid API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"Your plan's limit has been reached.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"The API key's role isn't allowed to do this.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found in this workspace.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited (120 requests/minute per key). See Retry-After.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/evidence/{id}":{"get":{"tags":["Controls & evidence"],"summary":"Get evidence metadata","x-v77-min-role":"auditor","parameters":[{"name":"id","in":"path","required":true,"description":"Evidence id.","schema":{"type":"string"}}],"responses":{"200":{"description":"Success.","headers":{"X-Request-Id":{"$ref":"#/components/headers/RequestId"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/RateLimitRemaining"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Evidence"}}}},"401":{"description":"Missing or invalid API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"The API key's role isn't allowed to do this.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found in this workspace.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited (120 requests/minute per key). See Retry-After.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/evidence/{id}/content":{"get":{"tags":["Controls & evidence"],"summary":"Download an evidence file","description":"The X-V77-SHA256 header carries the hash recorded at upload, so you can verify the file.","x-v77-min-role":"auditor","parameters":[{"name":"id","in":"path","required":true,"description":"Evidence id.","schema":{"type":"string"}}],"responses":{"200":{"description":"Success.","headers":{"X-Request-Id":{"$ref":"#/components/headers/RequestId"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/RateLimitRemaining"}},"content":{"application/json":{"schema":{"type":"string","format":"binary"}}}},"401":{"description":"Missing or invalid API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"The API key's role isn't allowed to do this.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found in this workspace.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited (120 requests/minute per key). See Retry-After.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/findings":{"get":{"tags":["Findings & incidents"],"summary":"List findings","x-v77-min-role":"auditor","parameters":[{"name":"limit","in":"query","required":false,"description":"Items per page, 1–100.","schema":{"type":"integer","minimum":1,"maximum":100,"default":25}},{"name":"cursor","in":"query","required":false,"description":"next_cursor from the previous page.","schema":{"type":"string"}},{"name":"systemId","in":"query","required":false,"description":"Filter by system.","schema":{"type":"string"}},{"name":"status","in":"query","required":false,"description":"Filter by status.","schema":{"type":"string","enum":["open","in_progress","resolved","accepted"]}},{"name":"severity","in":"query","required":false,"description":"Filter by severity.","schema":{"type":"string","enum":["low","medium","high","critical"]}}],"responses":{"200":{"description":"Success.","headers":{"X-Request-Id":{"$ref":"#/components/headers/RequestId"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/RateLimitRemaining"}},"content":{"application/json":{"schema":{"type":"object","properties":{"object":{"const":"list"},"data":{"type":"array","items":{"$ref":"#/components/schemas/Finding"}},"has_more":{"type":"boolean"},"next_cursor":{"type":["string","null"],"description":"Pass as cursor to get the next page."}},"required":["object","data","has_more","next_cursor"]}}}},"400":{"description":"Invalid request (validation_failed, invalid_parameter, invalid_json…).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing or invalid API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"The API key's role isn't allowed to do this.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited (120 requests/minute per key). See Retry-After.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"post":{"tags":["Findings & incidents"],"summary":"Open a finding","description":"Record an issue from a model test, pen test or audit. Open high or critical findings block the compliance gate.","x-v77-min-role":"ai_owner","parameters":[{"$ref":"#/components/parameters/IdempotencyKey"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["systemId","title"],"properties":{"systemId":{"type":"string"},"title":{"type":"string"},"description":{"type":"string"},"severity":{"type":"string","enum":["low","medium","high","critical"]},"frameworkRef":{"type":"string"}}},"example":{"systemId":"…","title":"Approval rate gap above 4/5ths rule","severity":"high","frameworkRef":"EU AI Act Art. 10(2)(f)"}}}},"responses":{"201":{"description":"Success.","headers":{"X-Request-Id":{"$ref":"#/components/headers/RequestId"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/RateLimitRemaining"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Finding"}}}},"400":{"description":"Invalid request (validation_failed, invalid_parameter, invalid_json…).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing or invalid API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"The API key's role isn't allowed to do this.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found in this workspace.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited (120 requests/minute per key). See Retry-After.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/findings/{id}":{"get":{"tags":["Findings & incidents"],"summary":"Get a finding","x-v77-min-role":"auditor","parameters":[{"name":"id","in":"path","required":true,"description":"Finding id.","schema":{"type":"string"}}],"responses":{"200":{"description":"Success.","headers":{"X-Request-Id":{"$ref":"#/components/headers/RequestId"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/RateLimitRemaining"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Finding"}}}},"401":{"description":"Missing or invalid API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"The API key's role isn't allowed to do this.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found in this workspace.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited (120 requests/minute per key). See Retry-After.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"patch":{"tags":["Findings & incidents"],"summary":"Update a finding","x-v77-min-role":"ai_owner","parameters":[{"name":"id","in":"path","required":true,"description":"Finding id.","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"title":{"type":"string"},"description":{"type":"string"},"severity":{"type":"string","enum":["low","medium","high","critical"]},"status":{"type":"string","enum":["open","in_progress","resolved","accepted"]},"frameworkRef":{"type":"string"}},"additionalProperties":false}}}},"responses":{"200":{"description":"Success.","headers":{"X-Request-Id":{"$ref":"#/components/headers/RequestId"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/RateLimitRemaining"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Finding"}}}},"400":{"description":"Invalid request (validation_failed, invalid_parameter, invalid_json…).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing or invalid API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"The API key's role isn't allowed to do this.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found in this workspace.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited (120 requests/minute per key). See Retry-After.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/incidents":{"get":{"tags":["Findings & incidents"],"summary":"List incidents","x-v77-min-role":"auditor","parameters":[{"name":"limit","in":"query","required":false,"description":"Items per page, 1–100.","schema":{"type":"integer","minimum":1,"maximum":100,"default":25}},{"name":"cursor","in":"query","required":false,"description":"next_cursor from the previous page.","schema":{"type":"string"}},{"name":"systemId","in":"query","required":false,"description":"Filter by system.","schema":{"type":"string"}},{"name":"status","in":"query","required":false,"description":"Filter by status.","schema":{"type":"string"}},{"name":"serious","in":"query","required":false,"description":"true for serious incidents only.","schema":{"type":"boolean"}}],"responses":{"200":{"description":"Success.","headers":{"X-Request-Id":{"$ref":"#/components/headers/RequestId"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/RateLimitRemaining"}},"content":{"application/json":{"schema":{"type":"object","properties":{"object":{"const":"list"},"data":{"type":"array","items":{"$ref":"#/components/schemas/Incident"}},"has_more":{"type":"boolean"},"next_cursor":{"type":["string","null"],"description":"Pass as cursor to get the next page."}},"required":["object","data","has_more","next_cursor"]}}}},"400":{"description":"Invalid request (validation_failed, invalid_parameter, invalid_json…).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing or invalid API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"The API key's role isn't allowed to do this.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited (120 requests/minute per key). See Retry-After.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"post":{"tags":["Findings & incidents"],"summary":"Report an incident","description":"Logs an incident and computes its reporting deadlines from awareAt: EU AI Act Art. 73 (15 days, 10 days for a death, 2 days for widespread or critical-infrastructure harm), DORA major-incident reports, GDPR Art. 33 (72 hours).","x-v77-min-role":"ai_owner","parameters":[{"$ref":"#/components/parameters/IdempotencyKey"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["title"],"properties":{"systemId":{"type":"string"},"title":{"type":"string"},"description":{"type":"string"},"severity":{"type":"string","enum":["low","medium","high","critical"]},"status":{"type":"string","enum":["open","investigating","mitigated","closed"]},"seriousIncident":{"type":"boolean"},"euArticleRef":{"type":"string","enum":["Art. 73(2)","Art. 73(3)","Art. 73(4)"]},"awareAt":{"type":"string","format":"date-time"},"occurredAt":{"type":"string","format":"date-time"},"impactSummary":{"type":"string"},"doraMajor":{"type":"boolean"},"gdprBreach":{"type":"boolean"}}},"example":{"systemId":"…","title":"Scoring model rejected eligible applicants","severity":"high","seriousIncident":true,"euArticleRef":"Art. 73(2)","awareAt":"2026-11-01T09:00:00Z","gdprBreach":false}}}},"responses":{"201":{"description":"Success.","headers":{"X-Request-Id":{"$ref":"#/components/headers/RequestId"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/RateLimitRemaining"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Incident"}}}},"400":{"description":"Invalid request (validation_failed, invalid_parameter, invalid_json…).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing or invalid API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"The API key's role isn't allowed to do this.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found in this workspace.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited (120 requests/minute per key). See Retry-After.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/incidents/{id}":{"get":{"tags":["Findings & incidents"],"summary":"Get an incident","x-v77-min-role":"auditor","parameters":[{"name":"id","in":"path","required":true,"description":"Incident id.","schema":{"type":"string"}}],"responses":{"200":{"description":"Success.","headers":{"X-Request-Id":{"$ref":"#/components/headers/RequestId"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/RateLimitRemaining"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Incident"}}}},"401":{"description":"Missing or invalid API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"The API key's role isn't allowed to do this.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found in this workspace.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited (120 requests/minute per key). See Retry-After.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"patch":{"tags":["Findings & incidents"],"summary":"Update an incident","description":"Send authorityNotifiedAt, gdprNotifiedAt or doraInitialAt / doraIntermediateAt / doraFinalAt to record that a report was filed; the matching deadline becomes done.","x-v77-min-role":"ai_owner","parameters":[{"name":"id","in":"path","required":true,"description":"Incident id.","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"title":{"type":"string"},"description":{"type":"string"},"severity":{"type":"string","enum":["low","medium","high","critical"]},"status":{"type":"string","enum":["open","investigating","mitigated","closed"]},"impactSummary":{"type":"string"},"rootCause":{"type":"string"},"correctiveActions":{"type":"string"},"authorityNotifiedAt":{"type":"string","format":"date-time"},"gdprNotifiedAt":{"type":"string","format":"date-time"},"doraInitialAt":{"type":"string","format":"date-time"},"doraIntermediateAt":{"type":"string","format":"date-time"},"doraFinalAt":{"type":"string","format":"date-time"}},"additionalProperties":false}}}},"responses":{"200":{"description":"Success.","headers":{"X-Request-Id":{"$ref":"#/components/headers/RequestId"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/RateLimitRemaining"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Incident"}}}},"400":{"description":"Invalid request (validation_failed, invalid_parameter, invalid_json…).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing or invalid API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"The API key's role isn't allowed to do this.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found in this workspace.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited (120 requests/minute per key). See Retry-After.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/systems/{id}/redteam-runs":{"get":{"tags":["Testing"],"summary":"List red-team runs","x-v77-min-role":"auditor","parameters":[{"name":"id","in":"path","required":true,"description":"AI system id.","schema":{"type":"string"}},{"name":"limit","in":"query","required":false,"description":"Items per page, 1–100.","schema":{"type":"integer","minimum":1,"maximum":100,"default":25}},{"name":"cursor","in":"query","required":false,"description":"next_cursor from the previous page.","schema":{"type":"string"}}],"responses":{"200":{"description":"Success.","headers":{"X-Request-Id":{"$ref":"#/components/headers/RequestId"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/RateLimitRemaining"}},"content":{"application/json":{"schema":{"type":"object","properties":{"object":{"const":"list"},"data":{"type":"array","items":{"$ref":"#/components/schemas/RedteamRun"}},"has_more":{"type":"boolean"},"next_cursor":{"type":["string","null"],"description":"Pass as cursor to get the next page."}},"required":["object","data","has_more","next_cursor"]}}}},"401":{"description":"Missing or invalid API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"The API key's role isn't allowed to do this.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found in this workspace.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited (120 requests/minute per key). See Retry-After.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"post":{"tags":["Testing"],"summary":"Run the red-team suite","description":"Sends 16 adversarial scenarios (jailbreaks, prompt injection, data leaks, harmful content, tool misuse; mapped to OWASP LLM Top 10 and EU AI Act Art. 15) to a configured provider or your own HTTPS chat endpoint. Runs synchronously (typically 10–60 s). targetAuthToken is used for this run only and never stored.","x-v77-min-role":"ai_owner","parameters":[{"name":"id","in":"path","required":true,"description":"AI system id.","schema":{"type":"string"}},{"$ref":"#/components/parameters/IdempotencyKey"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"provider":{"type":"string","description":"mock, openai, anthropic, azure, workers_ai (if configured)."},"systemPrompt":{"type":"string","description":"Your production system prompt, to test your guardrails."},"targetEndpointUrl":{"type":"string","description":"HTTPS endpoint accepting {messages:[…]} and returning {content} or OpenAI-style choices."},"targetAuthToken":{"type":"string","description":"Sent as Bearer token to targetEndpointUrl."}}},"example":{"targetEndpointUrl":"https://ai.example.eu/v1/chat","targetAuthToken":"…","systemPrompt":"You are a banking assistant…"}}}},"responses":{"201":{"description":"Success.","headers":{"X-Request-Id":{"$ref":"#/components/headers/RequestId"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/RateLimitRemaining"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RedteamRun"}}}},"400":{"description":"Invalid request (validation_failed, invalid_parameter, invalid_json…).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing or invalid API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"The API key's role isn't allowed to do this.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found in this workspace.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited (120 requests/minute per key). See Retry-After.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"502":{"description":"The model under test failed to respond.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/redteam-runs/{id}":{"get":{"tags":["Testing"],"summary":"Get a red-team run","x-v77-min-role":"auditor","parameters":[{"name":"id","in":"path","required":true,"description":"Run id.","schema":{"type":"string"}}],"responses":{"200":{"description":"Success.","headers":{"X-Request-Id":{"$ref":"#/components/headers/RequestId"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/RateLimitRemaining"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RedteamRun"}}}},"401":{"description":"Missing or invalid API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"The API key's role isn't allowed to do this.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found in this workspace.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited (120 requests/minute per key). See Retry-After.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/compliance-gate":{"get":{"tags":["Release gate"],"summary":"Check the compliance gate","description":"Should this AI system ship? Checks control readiness (default ≥70%), open high/critical findings, Annex IV documentation and the latest red-team run. With strict=true a blocked gate returns 422 so your CI step fails.","x-v77-min-role":"auditor","parameters":[{"name":"systemId","in":"query","required":true,"description":"AI system id.","schema":{"type":"string"}},{"name":"minReadiness","in":"query","required":false,"description":"Required readiness percent, 0–100.","schema":{"type":"integer","default":70}},{"name":"strict","in":"query","required":false,"description":"Return 422 when blocked.","schema":{"type":"boolean","default":false}}],"responses":{"200":{"description":"Success.","headers":{"X-Request-Id":{"$ref":"#/components/headers/RequestId"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/RateLimitRemaining"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ComplianceGate"},"example":{"object":"compliance_gate","passed":false,"status":"blocked","readinessPercent":54,"blockers":["2 open high/critical finding(s) must be remediated before release.","High-risk control readiness is 54%, below required gate threshold of 70%."],"warnings":[]}}}},"400":{"description":"Invalid request (validation_failed, invalid_parameter, invalid_json…).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing or invalid API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"The API key's role isn't allowed to do this.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found in this workspace.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"Gate blocked (strict=true).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ComplianceGate"}}}},"429":{"description":"Rate limited (120 requests/minute per key). See Retry-After.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/audit-log":{"get":{"tags":["Audit trail"],"summary":"List audit events","description":"Append-only, SHA-256 hash-chained record of every change in the workspace, newest first.","x-v77-min-role":"auditor","parameters":[{"name":"limit","in":"query","required":false,"description":"Items per page, 1–100.","schema":{"type":"integer","minimum":1,"maximum":100,"default":25}},{"name":"cursor","in":"query","required":false,"description":"next_cursor from the previous page.","schema":{"type":"string"}},{"name":"action","in":"query","required":false,"description":"e.g. system.classified","schema":{"type":"string"}},{"name":"entityType","in":"query","required":false,"description":"e.g. ai_system","schema":{"type":"string"}},{"name":"entityId","in":"query","required":false,"description":"Entity id.","schema":{"type":"string"}}],"responses":{"200":{"description":"Success.","headers":{"X-Request-Id":{"$ref":"#/components/headers/RequestId"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/RateLimitRemaining"}},"content":{"application/json":{"schema":{"type":"object","properties":{"object":{"const":"list"},"data":{"type":"array","items":{"$ref":"#/components/schemas/AuditEvent"}},"has_more":{"type":"boolean"},"next_cursor":{"type":["string","null"],"description":"Pass as cursor to get the next page."}},"required":["object","data","has_more","next_cursor"]}}}},"400":{"description":"Invalid request (validation_failed, invalid_parameter, invalid_json…).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing or invalid API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"The API key's role isn't allowed to do this.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited (120 requests/minute per key). See Retry-After.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/audit-log/verify":{"get":{"tags":["Audit trail"],"summary":"Verify the audit chain","description":"Recomputes every hash and reports whether any entry was altered, removed or reordered.","x-v77-min-role":"auditor","responses":{"200":{"description":"Success.","headers":{"X-Request-Id":{"$ref":"#/components/headers/RequestId"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/RateLimitRemaining"}},"content":{"application/json":{"schema":{"type":"object","properties":{"object":{"const":"audit_chain_verification"},"valid":{"type":"boolean"},"entries":{"type":"integer"},"firstBrokenEntryId":{"type":["string","null"]},"reason":{"type":["string","null"]},"headSha256":{"type":["string","null"]},"verifiedAt":{"type":"string","format":"date-time"}}}}}},"401":{"description":"Missing or invalid API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"The API key's role isn't allowed to do this.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited (120 requests/minute per key). See Retry-After.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/webhook-events":{"get":{"tags":["Webhooks"],"summary":"List event types","x-v77-min-role":"auditor","responses":{"200":{"description":"Success.","headers":{"X-Request-Id":{"$ref":"#/components/headers/RequestId"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/RateLimitRemaining"}},"content":{"application/json":{"schema":{"type":"object"}}}},"401":{"description":"Missing or invalid API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"The API key's role isn't allowed to do this.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited (120 requests/minute per key). See Retry-After.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/webhook-endpoints":{"get":{"tags":["Webhooks"],"summary":"List webhook endpoints","x-v77-min-role":"admin","responses":{"200":{"description":"Success.","headers":{"X-Request-Id":{"$ref":"#/components/headers/RequestId"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/RateLimitRemaining"}},"content":{"application/json":{"schema":{"type":"object","properties":{"object":{"const":"list"},"data":{"type":"array","items":{"$ref":"#/components/schemas/WebhookEndpoint"}},"has_more":{"type":"boolean"},"next_cursor":{"type":["string","null"],"description":"Pass as cursor to get the next page."}},"required":["object","data","has_more","next_cursor"]}}}},"401":{"description":"Missing or invalid API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"The API key's role isn't allowed to do this.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited (120 requests/minute per key). See Retry-After.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"post":{"tags":["Webhooks"],"summary":"Create a webhook endpoint","description":"The signing secret is in this response only.","x-v77-min-role":"admin","parameters":[{"$ref":"#/components/parameters/IdempotencyKey"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["url","events"],"properties":{"url":{"type":"string","description":"Public HTTPS URL."},"events":{"type":"array","items":{"type":"string"}}}},"example":{"url":"https://grc.example.eu/hooks/v77","events":["system.tier_changed","incident.created"]}}}},"responses":{"201":{"description":"Success.","headers":{"X-Request-Id":{"$ref":"#/components/headers/RequestId"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/RateLimitRemaining"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookEndpoint"}}}},"400":{"description":"Invalid request (validation_failed, invalid_parameter, invalid_json…).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing or invalid API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"The API key's role isn't allowed to do this.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited (120 requests/minute per key). See Retry-After.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/webhook-endpoints/{id}":{"delete":{"tags":["Webhooks"],"summary":"Delete a webhook endpoint","x-v77-min-role":"admin","parameters":[{"name":"id","in":"path","required":true,"description":"Endpoint id.","schema":{"type":"string"}}],"responses":{"200":{"description":"Success.","headers":{"X-Request-Id":{"$ref":"#/components/headers/RequestId"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/RateLimitRemaining"}},"content":{"application/json":{"schema":{"type":"object","properties":{"object":{"const":"webhook_endpoint"},"id":{"type":"string"},"deleted":{"const":true}}}}}},"401":{"description":"Missing or invalid API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"The API key's role isn't allowed to do this.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found in this workspace.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited (120 requests/minute per key). See Retry-After.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}}},"webhooks":{"system.created":{"post":{"summary":"system.created","parameters":[{"name":"X-V77-Event","in":"header","schema":{"type":"string"}},{"name":"X-V77-Delivery","in":"header","schema":{"type":"string"}},{"name":"X-V77-Signature","in":"header","description":"t=<unix seconds>,v1=<hex HMAC-SHA256 of `${t}.${rawBody}` with your endpoint secret>","schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string","description":"Delivery id (same as X-V77-Delivery)."},"event":{"const":"system.created"},"createdAt":{"type":"string","format":"date-time"},"orgId":{"type":"string"},"data":{"type":"object","properties":{"systemId":{"type":"string"},"name":{"type":"string"}}}}}}}},"responses":{"2XX":{"description":"Return any 2xx within 5 seconds to acknowledge. Deliveries are not retried automatically; see Settings → Webhooks for the delivery log."}}}},"system.tier_changed":{"post":{"summary":"system.tier_changed","parameters":[{"name":"X-V77-Event","in":"header","schema":{"type":"string"}},{"name":"X-V77-Delivery","in":"header","schema":{"type":"string"}},{"name":"X-V77-Signature","in":"header","description":"t=<unix seconds>,v1=<hex HMAC-SHA256 of `${t}.${rawBody}` with your endpoint secret>","schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string","description":"Delivery id (same as X-V77-Delivery)."},"event":{"const":"system.tier_changed"},"createdAt":{"type":"string","format":"date-time"},"orgId":{"type":"string"},"data":{"type":"object","properties":{"systemId":{"type":"string"},"name":{"type":"string"},"previousTier":{"type":["string","null"]},"riskTier":{"type":"string"}}}}}}}},"responses":{"2XX":{"description":"Return any 2xx within 5 seconds to acknowledge. Deliveries are not retried automatically; see Settings → Webhooks for the delivery log."}}}},"evidence.added":{"post":{"summary":"evidence.added","parameters":[{"name":"X-V77-Event","in":"header","schema":{"type":"string"}},{"name":"X-V77-Delivery","in":"header","schema":{"type":"string"}},{"name":"X-V77-Signature","in":"header","description":"t=<unix seconds>,v1=<hex HMAC-SHA256 of `${t}.${rawBody}` with your endpoint secret>","schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string","description":"Delivery id (same as X-V77-Delivery)."},"event":{"const":"evidence.added"},"createdAt":{"type":"string","format":"date-time"},"orgId":{"type":"string"},"data":{"type":"object","properties":{"evidenceId":{"type":"string"},"title":{"type":"string"},"sha256":{"type":"string"},"systemId":{"type":["string","null"]},"controlId":{"type":["string","null"]}}}}}}}},"responses":{"2XX":{"description":"Return any 2xx within 5 seconds to acknowledge. Deliveries are not retried automatically; see Settings → Webhooks for the delivery log."}}}},"finding.created":{"post":{"summary":"finding.created","parameters":[{"name":"X-V77-Event","in":"header","schema":{"type":"string"}},{"name":"X-V77-Delivery","in":"header","schema":{"type":"string"}},{"name":"X-V77-Signature","in":"header","description":"t=<unix seconds>,v1=<hex HMAC-SHA256 of `${t}.${rawBody}` with your endpoint secret>","schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string","description":"Delivery id (same as X-V77-Delivery)."},"event":{"const":"finding.created"},"createdAt":{"type":"string","format":"date-time"},"orgId":{"type":"string"},"data":{"type":"object","properties":{"findingId":{"type":"string"},"systemId":{"type":"string"},"title":{"type":"string"},"severity":{"type":"string"}}}}}}}},"responses":{"2XX":{"description":"Return any 2xx within 5 seconds to acknowledge. Deliveries are not retried automatically; see Settings → Webhooks for the delivery log."}}}},"incident.created":{"post":{"summary":"incident.created","parameters":[{"name":"X-V77-Event","in":"header","schema":{"type":"string"}},{"name":"X-V77-Delivery","in":"header","schema":{"type":"string"}},{"name":"X-V77-Signature","in":"header","description":"t=<unix seconds>,v1=<hex HMAC-SHA256 of `${t}.${rawBody}` with your endpoint secret>","schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string","description":"Delivery id (same as X-V77-Delivery)."},"event":{"const":"incident.created"},"createdAt":{"type":"string","format":"date-time"},"orgId":{"type":"string"},"data":{"type":"object","properties":{"incidentId":{"type":"string"},"title":{"type":"string"},"severity":{"type":"string"},"seriousIncident":{"type":"boolean"},"doraMajor":{"type":"boolean"},"gdprBreach":{"type":"boolean"}}}}}}}},"responses":{"2XX":{"description":"Return any 2xx within 5 seconds to acknowledge. Deliveries are not retried automatically; see Settings → Webhooks for the delivery log."}}}},"discovery.new_asset":{"post":{"summary":"discovery.new_asset","parameters":[{"name":"X-V77-Event","in":"header","schema":{"type":"string"}},{"name":"X-V77-Delivery","in":"header","schema":{"type":"string"}},{"name":"X-V77-Signature","in":"header","description":"t=<unix seconds>,v1=<hex HMAC-SHA256 of `${t}.${rawBody}` with your endpoint secret>","schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string","description":"Delivery id (same as X-V77-Delivery)."},"event":{"const":"discovery.new_asset"},"createdAt":{"type":"string","format":"date-time"},"orgId":{"type":"string"},"data":{"type":"object"}}}}}},"responses":{"2XX":{"description":"Return any 2xx within 5 seconds to acknowledge. Deliveries are not retried automatically; see Settings → Webhooks for the delivery log."}}}}}}