443 lines
18 KiB
YAML
443 lines
18 KiB
YAML
openapi: 3.1.0
|
|
info:
|
|
title: AI Usage Disclosure API
|
|
version: 2.0.2
|
|
description: >-
|
|
Stateless multilingual API for visible and machine-readable AI usage declarations,
|
|
non-binding Article 50 decision support, validation and optional licensed bulk/export capabilities.
|
|
servers:
|
|
- url: https://ai.example.org
|
|
paths:
|
|
/badge/{preset}.svg:
|
|
get:
|
|
summary: Render a standard preset badge
|
|
parameters:
|
|
- name: preset
|
|
in: path
|
|
required: true
|
|
schema: {type: string, enum: [no-ai, research, summary, full]}
|
|
- {$ref: '#/components/parameters/language'}
|
|
- {$ref: '#/components/parameters/theme'}
|
|
- {$ref: '#/components/parameters/style'}
|
|
- name: link
|
|
in: query
|
|
schema: {type: string, description: Use auto to link to the generated declaration page.}
|
|
responses:
|
|
"200":
|
|
description: SVG badge
|
|
content:
|
|
image/svg+xml: {schema: {type: string}}
|
|
/v1/badge.svg:
|
|
get:
|
|
summary: Render an SVG badge from declaration parameters
|
|
description: Custom labels and colours require the licensed capability `custom_badge`.
|
|
parameters:
|
|
- {$ref: '#/components/parameters/commonMode'}
|
|
- {$ref: '#/components/parameters/preset'}
|
|
- {$ref: '#/components/parameters/extent'}
|
|
- {$ref: '#/components/parameters/language'}
|
|
- {$ref: '#/components/parameters/component'}
|
|
- {$ref: '#/components/parameters/activities'}
|
|
- {$ref: '#/components/parameters/review'}
|
|
- {$ref: '#/components/parameters/assurance'}
|
|
- {$ref: '#/components/parameters/publicInterestText'}
|
|
- {$ref: '#/components/parameters/deepfake'}
|
|
- {$ref: '#/components/parameters/theme'}
|
|
- {$ref: '#/components/parameters/style'}
|
|
- {name: link, in: query, schema: {type: string}}
|
|
- {$ref: '#/components/parameters/badgeLabel'}
|
|
- {$ref: '#/components/parameters/badgeMessage'}
|
|
- {$ref: '#/components/parameters/leftColor'}
|
|
- {$ref: '#/components/parameters/rightColor'}
|
|
responses:
|
|
"200":
|
|
description: SVG badge
|
|
content:
|
|
image/svg+xml: {schema: {type: string}}
|
|
"403": {$ref: '#/components/responses/LicensedCapabilityRequired'}
|
|
/declaration:
|
|
get:
|
|
summary: Render a human-readable declaration page
|
|
parameters:
|
|
- {$ref: '#/components/parameters/commonMode'}
|
|
- {$ref: '#/components/parameters/preset'}
|
|
- {$ref: '#/components/parameters/extent'}
|
|
- {$ref: '#/components/parameters/language'}
|
|
- {$ref: '#/components/parameters/component'}
|
|
- {$ref: '#/components/parameters/activities'}
|
|
- {$ref: '#/components/parameters/review'}
|
|
- {name: subject, in: query, schema: {type: string, format: uri}}
|
|
- {name: responsible, in: query, schema: {type: string, maxLength: 200}}
|
|
- {name: responsibleUrl, in: query, schema: {type: string, format: uri}}
|
|
- {$ref: '#/components/parameters/assurance'}
|
|
- {$ref: '#/components/parameters/publicInterestText'}
|
|
- {$ref: '#/components/parameters/deepfake'}
|
|
- {$ref: '#/components/parameters/artisticContext'}
|
|
- {$ref: '#/components/parameters/substantialHumanReview'}
|
|
- {$ref: '#/components/parameters/editorialResponsibilityConfirmed'}
|
|
- {$ref: '#/components/parameters/firstExposureDisclosure'}
|
|
- {$ref: '#/components/parameters/accessibilityConsidered'}
|
|
- {$ref: '#/components/parameters/customTitle'}
|
|
- {$ref: '#/components/parameters/customDescription'}
|
|
- {$ref: '#/components/parameters/badgeLabel'}
|
|
- {$ref: '#/components/parameters/badgeMessage'}
|
|
- {$ref: '#/components/parameters/leftColor'}
|
|
- {$ref: '#/components/parameters/rightColor'}
|
|
responses:
|
|
"200": {description: Human-readable HTML declaration}
|
|
"403": {$ref: '#/components/responses/LicensedCapabilityRequired'}
|
|
/v1/declaration.json:
|
|
get:
|
|
summary: Generate a JSON-LD declaration
|
|
parameters:
|
|
- {$ref: '#/components/parameters/commonMode'}
|
|
- {$ref: '#/components/parameters/preset'}
|
|
- {$ref: '#/components/parameters/extent'}
|
|
- {$ref: '#/components/parameters/language'}
|
|
- {$ref: '#/components/parameters/component'}
|
|
- {$ref: '#/components/parameters/activities'}
|
|
- {$ref: '#/components/parameters/review'}
|
|
- {name: subject, in: query, schema: {type: string, format: uri}}
|
|
- {name: responsible, in: query, schema: {type: string, maxLength: 200}}
|
|
- {name: responsibleUrl, in: query, schema: {type: string, format: uri}}
|
|
- {$ref: '#/components/parameters/assurance'}
|
|
- {$ref: '#/components/parameters/publicInterestText'}
|
|
- {$ref: '#/components/parameters/deepfake'}
|
|
- {$ref: '#/components/parameters/artisticContext'}
|
|
- {$ref: '#/components/parameters/substantialHumanReview'}
|
|
- {$ref: '#/components/parameters/editorialResponsibilityConfirmed'}
|
|
- {$ref: '#/components/parameters/firstExposureDisclosure'}
|
|
- {$ref: '#/components/parameters/accessibilityConsidered'}
|
|
- {$ref: '#/components/parameters/customTitle'}
|
|
- {$ref: '#/components/parameters/customDescription'}
|
|
- {$ref: '#/components/parameters/badgeLabel'}
|
|
- {$ref: '#/components/parameters/badgeMessage'}
|
|
- {$ref: '#/components/parameters/leftColor'}
|
|
- {$ref: '#/components/parameters/rightColor'}
|
|
responses:
|
|
"200":
|
|
description: JSON-LD declaration
|
|
content:
|
|
application/ld+json:
|
|
schema: {$ref: './schema/declaration.schema.json'}
|
|
"403": {$ref: '#/components/responses/LicensedCapabilityRequired'}
|
|
/v1/article50-assessment.json:
|
|
get:
|
|
summary: Return non-binding technical Article 50 decision support
|
|
description: >-
|
|
Evaluates the factual regulatory context supplied with a declaration. The result is
|
|
technical decision support, not legal advice or a legal determination.
|
|
parameters:
|
|
- {$ref: '#/components/parameters/commonMode'}
|
|
- {$ref: '#/components/parameters/preset'}
|
|
- {$ref: '#/components/parameters/extent'}
|
|
- {$ref: '#/components/parameters/language'}
|
|
- {$ref: '#/components/parameters/component'}
|
|
- {$ref: '#/components/parameters/activities'}
|
|
- {$ref: '#/components/parameters/review'}
|
|
- {name: subject, in: query, schema: {type: string, format: uri}}
|
|
- {name: responsible, in: query, schema: {type: string, maxLength: 200}}
|
|
- {name: responsibleUrl, in: query, schema: {type: string, format: uri}}
|
|
- {$ref: '#/components/parameters/assurance'}
|
|
- {$ref: '#/components/parameters/publicInterestText'}
|
|
- {$ref: '#/components/parameters/deepfake'}
|
|
- {$ref: '#/components/parameters/artisticContext'}
|
|
- {$ref: '#/components/parameters/substantialHumanReview'}
|
|
- {$ref: '#/components/parameters/editorialResponsibilityConfirmed'}
|
|
- {$ref: '#/components/parameters/firstExposureDisclosure'}
|
|
- {$ref: '#/components/parameters/accessibilityConsidered'}
|
|
- {$ref: '#/components/parameters/customTitle'}
|
|
- {$ref: '#/components/parameters/customDescription'}
|
|
- {$ref: '#/components/parameters/badgeLabel'}
|
|
- {$ref: '#/components/parameters/badgeMessage'}
|
|
- {$ref: '#/components/parameters/leftColor'}
|
|
- {$ref: '#/components/parameters/rightColor'}
|
|
responses:
|
|
"200":
|
|
description: Assessment with localized summary and warnings
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
required: [assessment, title, summary, disclaimer]
|
|
properties:
|
|
assessment: {$ref: '#/components/schemas/Article50Assessment'}
|
|
title: {type: string}
|
|
summary: {type: string}
|
|
findings: {type: array, items: {type: string}}
|
|
warnings: {type: array, items: {type: string}}
|
|
disclaimer: {type: string}
|
|
/v1/declaration.bundle.json:
|
|
get:
|
|
summary: Export a declaration evidence bundle
|
|
description: Requires the licensed capability `export_bundle`.
|
|
parameters:
|
|
- {$ref: '#/components/parameters/commonMode'}
|
|
- {$ref: '#/components/parameters/preset'}
|
|
- {$ref: '#/components/parameters/extent'}
|
|
- {$ref: '#/components/parameters/language'}
|
|
- {$ref: '#/components/parameters/component'}
|
|
- {$ref: '#/components/parameters/activities'}
|
|
- {$ref: '#/components/parameters/review'}
|
|
- {name: subject, in: query, schema: {type: string, format: uri}}
|
|
- {name: responsible, in: query, schema: {type: string, maxLength: 200}}
|
|
- {name: responsibleUrl, in: query, schema: {type: string, format: uri}}
|
|
- {$ref: '#/components/parameters/assurance'}
|
|
- {$ref: '#/components/parameters/publicInterestText'}
|
|
- {$ref: '#/components/parameters/deepfake'}
|
|
- {$ref: '#/components/parameters/artisticContext'}
|
|
- {$ref: '#/components/parameters/substantialHumanReview'}
|
|
- {$ref: '#/components/parameters/editorialResponsibilityConfirmed'}
|
|
- {$ref: '#/components/parameters/firstExposureDisclosure'}
|
|
- {$ref: '#/components/parameters/accessibilityConsidered'}
|
|
- {$ref: '#/components/parameters/customTitle'}
|
|
- {$ref: '#/components/parameters/customDescription'}
|
|
- {$ref: '#/components/parameters/badgeLabel'}
|
|
- {$ref: '#/components/parameters/badgeMessage'}
|
|
- {$ref: '#/components/parameters/leftColor'}
|
|
- {$ref: '#/components/parameters/rightColor'}
|
|
responses:
|
|
"200":
|
|
description: Declaration, Article 50 assessment, SHA-256 declaration digest and canonical output URLs
|
|
content:
|
|
application/json:
|
|
schema: {$ref: '#/components/schemas/DeclarationBundle'}
|
|
"403": {$ref: '#/components/responses/LicensedCapabilityRequired'}
|
|
/v1/bulk/declarations:
|
|
post:
|
|
summary: Process multiple declarations in one server-to-server request
|
|
description: >-
|
|
Requires the licensed capability `bulk_api`. The dedicated bulk container additionally
|
|
requires an API key by default and enforces configured/licensed item limits.
|
|
security:
|
|
- bulkBearer: []
|
|
- bulkApiKey: []
|
|
requestBody:
|
|
required: true
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
additionalProperties: false
|
|
required: [items]
|
|
properties:
|
|
items:
|
|
type: array
|
|
minItems: 1
|
|
items:
|
|
type: object
|
|
additionalProperties: false
|
|
properties:
|
|
id: {type: string}
|
|
parameters:
|
|
type: object
|
|
additionalProperties: {type: string}
|
|
required: [parameters]
|
|
responses:
|
|
"200":
|
|
description: Per-item declaration and assessment results
|
|
"401":
|
|
description: Bulk API authentication required when configured
|
|
"403": {$ref: '#/components/responses/LicensedCapabilityRequired'}
|
|
"413": {description: Configured or licensed bulk limit exceeded}
|
|
/v1/validate:
|
|
post:
|
|
summary: Validate an AI usage declaration
|
|
requestBody:
|
|
required: true
|
|
content:
|
|
application/json:
|
|
schema: {$ref: './schema/declaration.schema.json'}
|
|
responses:
|
|
"200": {description: Valid declaration}
|
|
"422": {description: Validation failed}
|
|
/v1/capabilities:
|
|
get:
|
|
summary: Return runtime mode, licence state, licensed capabilities and languages
|
|
responses:
|
|
"200":
|
|
description: Runtime capabilities
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
properties:
|
|
product: {type: string, const: ai-disclosure-standard}
|
|
productVersion: {type: string}
|
|
schemaVersion: {type: string}
|
|
serviceMode: {type: string, enum: [full, api, bulk]}
|
|
license: {type: object}
|
|
supportedLanguages:
|
|
type: array
|
|
items: {type: string, enum: [de, en, fr, es, it, nl, pt, pl]}
|
|
licensedCapabilities:
|
|
type: object
|
|
additionalProperties: {type: boolean}
|
|
/healthz:
|
|
get:
|
|
summary: Liveness endpoint
|
|
responses: {"200": {description: Healthy}}
|
|
/readyz:
|
|
get:
|
|
summary: Readiness endpoint
|
|
description: In bulk mode this also checks the bulk licence capability and required API-key configuration.
|
|
responses:
|
|
"200": {description: Ready}
|
|
"503": {description: Runtime is not ready}
|
|
/metrics:
|
|
get:
|
|
summary: Prometheus metrics
|
|
responses: {"200": {description: Prometheus text exposition}}
|
|
components:
|
|
securitySchemes:
|
|
bulkBearer:
|
|
type: http
|
|
scheme: bearer
|
|
bulkApiKey:
|
|
type: apiKey
|
|
in: header
|
|
name: X-API-Key
|
|
parameters:
|
|
commonMode:
|
|
name: mode
|
|
in: query
|
|
schema: {type: string, enum: [single, article]}
|
|
preset:
|
|
name: preset
|
|
in: query
|
|
schema: {type: string, enum: [no-ai, research, summary, full]}
|
|
extent:
|
|
name: extent
|
|
in: query
|
|
schema: {type: string, enum: [none, assisted, partial, mostly, full], default: assisted}
|
|
language:
|
|
name: lang
|
|
in: query
|
|
schema: {type: string, enum: [de, en, fr, es, it, nl, pt, pl]}
|
|
component:
|
|
name: component
|
|
in: query
|
|
schema: {type: string, enum: [text, coverImage, image, research, translation, audio, video, code, other], default: text}
|
|
activities:
|
|
name: activities
|
|
in: query
|
|
schema: {type: string, description: Comma-separated activity identifiers.}
|
|
review:
|
|
name: review
|
|
in: query
|
|
schema: {type: string, enum: [none, basic, editorial, expert], default: editorial}
|
|
assurance:
|
|
name: assurance
|
|
in: query
|
|
description: Evidence basis for the declaration.
|
|
schema: {type: string, enum: [selfDeclared, technicallyRecorded, signed, verified], default: selfDeclared}
|
|
publicInterestText:
|
|
name: publicInterestText
|
|
in: query
|
|
description: Factual flag that the text informs the public on a matter of public interest.
|
|
schema: {type: boolean}
|
|
deepfake:
|
|
name: deepfake
|
|
in: query
|
|
description: Factual flag for deepfake or realistic AI-generated/manipulated content.
|
|
schema: {type: boolean}
|
|
artisticContext:
|
|
name: artisticCreativeSatiricalFictional
|
|
in: query
|
|
schema: {type: boolean}
|
|
substantialHumanReview:
|
|
name: substantialHumanReview
|
|
in: query
|
|
schema: {type: boolean}
|
|
editorialResponsibilityConfirmed:
|
|
name: editorialResponsibilityConfirmed
|
|
in: query
|
|
schema: {type: boolean}
|
|
firstExposureDisclosure:
|
|
name: firstExposureDisclosure
|
|
in: query
|
|
schema: {type: boolean}
|
|
accessibilityConsidered:
|
|
name: accessibilityConsidered
|
|
in: query
|
|
schema: {type: boolean}
|
|
theme:
|
|
name: theme
|
|
in: query
|
|
schema: {type: string, enum: [mono, color], default: color}
|
|
style:
|
|
name: style
|
|
in: query
|
|
schema: {type: string, enum: [flat, flat-square], default: flat}
|
|
customTitle:
|
|
name: customTitle
|
|
in: query
|
|
description: Licensed capability `custom_text`.
|
|
schema: {type: string, maxLength: 120}
|
|
customDescription:
|
|
name: customDescription
|
|
in: query
|
|
description: Licensed capability `custom_text`.
|
|
schema: {type: string, maxLength: 500}
|
|
badgeLabel:
|
|
name: badgeLabel
|
|
in: query
|
|
description: Licensed capability `custom_badge`.
|
|
schema: {type: string, maxLength: 40}
|
|
badgeMessage:
|
|
name: badgeMessage
|
|
in: query
|
|
description: Licensed capability `custom_badge`.
|
|
schema: {type: string, maxLength: 80}
|
|
leftColor:
|
|
name: leftColor
|
|
in: query
|
|
description: Licensed capability `custom_badge`.
|
|
schema: {type: string, pattern: '^#[0-9A-Fa-f]{6}$'}
|
|
rightColor:
|
|
name: rightColor
|
|
in: query
|
|
description: Licensed capability `custom_badge`.
|
|
schema: {type: string, pattern: '^#[0-9A-Fa-f]{6}$'}
|
|
schemas:
|
|
Article50Assessment:
|
|
type: object
|
|
required: [code, severity, potentiallyApplicable]
|
|
properties:
|
|
code: {type: string}
|
|
severity: {type: string, enum: [neutral, caution, attention]}
|
|
potentiallyApplicable: {type: boolean}
|
|
findings:
|
|
type: array
|
|
items:
|
|
type: object
|
|
required: [code, severity]
|
|
properties:
|
|
code: {type: string}
|
|
severity: {type: string, enum: [neutral, caution, attention]}
|
|
warnings: {type: array, items: {type: string}}
|
|
DeclarationBundle:
|
|
type: object
|
|
required: [product, productVersion, generatedAt, declaration, declarationDigest, article50Assessment, declarationUrl, manifestUrl, badgeUrl]
|
|
properties:
|
|
product: {type: string, const: ai-disclosure-standard}
|
|
productVersion: {type: string}
|
|
generatedAt: {type: string, format: date-time}
|
|
declaration: {$ref: './schema/declaration.schema.json'}
|
|
declarationDigest: {type: string, pattern: '^sha256:[0-9a-f]{64}$'}
|
|
article50Assessment: {$ref: '#/components/schemas/Article50Assessment'}
|
|
declarationUrl: {type: string, format: uri}
|
|
manifestUrl: {type: string, format: uri}
|
|
badgeUrl: {type: string, format: uri}
|
|
responses:
|
|
LicensedCapabilityRequired:
|
|
description: A valid licensed capability is required
|
|
content:
|
|
application/problem+json:
|
|
schema:
|
|
type: object
|
|
properties:
|
|
code: {const: licensed_feature_required}
|
|
status: {const: 403}
|
|
detail: {type: string}
|