openapi: 3.1.0
info:
  title: Einvoi Control Partner API
  version: 1.0.0
  description: API structurée de contrôle explicable; aucun document PDF/XML brut n'est accepté.
servers:
  - url: https://api.einvoi.com
paths:
  /api/partner/v1/capabilities:
    get:
      operationId: getCapabilities
      security: [{ partnerBearer: [] }]
      responses:
        "200": { description: Capacités et scopes effectifs }
  /api/partner/v1/invoices/control:
    post:
      operationId: controlStructuredInvoice
      security: [{ partnerBearer: [] }]
      parameters: [{ $ref: "#/components/parameters/IdempotencyKey" }]
      requestBody:
        required: true
        content:
          application/json:
            schema: { $ref: "#/components/schemas/StructuredInvoice" }
      responses:
        "200":
          description: Contrôles déterministes et preuves
          content:
            application/json:
              schema: { $ref: "#/components/schemas/ControlResult" }
  /api/partner/v1/reconciliation:
    post:
      operationId: reconcileStructuredInvoices
      security: [{ partnerBearer: [] }]
      parameters: [{ $ref: "#/components/parameters/IdempotencyKey" }]
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required: [invoices]
              properties:
                invoices:
                  type: array
                  minItems: 2
                  maxItems: 100
                  items: { $ref: "#/components/schemas/StructuredInvoice" }
      responses:
        "200": { description: Contrôles et relations explicables }
  /api/partner/v1/relationships/evaluate:
    post:
      operationId: evaluateStructuredRelationship
      security: [{ partnerBearer: [] }]
      parameters: [{ $ref: "#/components/parameters/IdempotencyKey" }]
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required: [left, right]
              properties:
                left: { $ref: "#/components/schemas/StructuredInvoice" }
                right: { $ref: "#/components/schemas/StructuredInvoice" }
      responses:
        "200": { description: Relation déterministe ou NOT_VERIFIABLE }
components:
  securitySchemes:
    partnerBearer:
      type: http
      scheme: bearer
      bearerFormat: scoped Einvoi partner credential
  parameters:
    IdempotencyKey:
      in: header
      name: X-Idempotency-Key
      required: true
      schema: { type: string, minLength: 8, maxLength: 128 }
  schemas:
    StructuredInvoice:
      type: object
      additionalProperties: false
      required: [externalId, currency, provenance]
      properties:
        externalId: { type: string, maxLength: 128 }
        standard: { enum: [FACTUR_X, UBL, CII, OTHER] }
        profile: { type: string }
        version: { type: string }
        currency: { type: string, pattern: "^[A-Z]{3}$" }
        supplierId: { type: string }
        buyerId: { type: string }
        invoiceNumber: { type: string }
        issueDate: { type: string, format: date }
        taxExclusiveMinor: { type: integer }
        taxMinor: { type: integer }
        taxInclusiveMinor: { type: integer }
        payableMinor: { type: integer }
        provenance:
          type: array
          items:
            type: object
            required: [field, source]
            properties:
              field: { type: string }
              source:
                { enum: [PARTNER_DECLARED, PARTNER_CALCULATED, NOT_AVAILABLE] }
    ControlResult:
      type: object
      required: [engine, apiVersion, externalId, status, controls]
      properties:
        engine: { const: einvoi-control-v1 }
        apiVersion: { const: "2026-08-20" }
        externalId: { type: string }
        status: { enum: [PASS, FAIL, NOT_VERIFIABLE] }
        controls:
          type: array
          items:
            type: object
            required:
              [ruleId, status, provenance, evidence, recommendedHumanReview]
            properties:
              ruleId: { type: string }
              status: { enum: [PASS, FAIL, NOT_VERIFIABLE] }
              declaredMinor: { type: integer }
              calculatedMinor: { type: integer }
              differenceMinor: { type: integer }
              provenance: { type: array, items: { type: string } }
              evidence: { type: string }
              recommendedHumanReview: { type: boolean }
