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}