{
    "openapi": "3.1.0",
    "info": {
        "title": "TierSafe - API de veille",
        "version": "1.0.0",
        "summary": "Pousser un portefeuille de tiers, lire les événements détectés dans les sources officielles, recevoir des webhooks signés.",
        "description": "Documentation lisible : page « API de veille et webhooks » du site. Toute erreur porte un code machine stable (code) et un message lisible en français (detail). Les ajouts compatibles (nouveau champ, nouveau type d'événement) arrivent sans changer de version : ignorez ce que vous ne connaissez pas.",
        "contact": {
            "name": "TierSafe"
        }
    },
    "servers": [
        {
            "url": "https://tiersafe.eu/api/v1/monitoring"
        }
    ],
    "security": [
        {
            "bearerAuth": []
        }
    ],
    "paths": {
        "/subscription": {
            "get": {
                "operationId": "getSubscription",
                "summary": "État de l'abonnement et du portefeuille",
                "tags": [
                    "Portefeuille"
                ],
                "responses": {
                    "200": {
                        "description": "État courant",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Subscription"
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "429": {
                        "$ref": "#/components/responses/RateLimited"
                    }
                }
            }
        },
        "/companies": {
            "get": {
                "operationId": "listCompanies",
                "summary": "Fiches suivies, dans l'ordre d'ajout",
                "tags": [
                    "Portefeuille"
                ],
                "description": "Sans abonnement, alert_level, open_events et checked_at valent null.",
                "parameters": [
                    {
                        "name": "limit",
                        "in": "query",
                        "schema": {
                            "type": "integer",
                            "minimum": 1,
                            "maximum": 500,
                            "default": 100
                        }
                    },
                    {
                        "name": "offset",
                        "in": "query",
                        "schema": {
                            "type": "integer",
                            "minimum": 0,
                            "default": 0
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Page de fiches",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/CompanyList"
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "429": {
                        "$ref": "#/components/responses/RateLimited"
                    }
                }
            },
            "post": {
                "operationId": "pushCompanies",
                "summary": "Pousser un lot de tiers",
                "tags": [
                    "Portefeuille"
                ],
                "description": "Mêmes règles que l'import de fichier. En mode sync, les références absentes sont retirées et le lot doit être valide en entier.",
                "parameters": [
                    {
                        "name": "dry_run",
                        "in": "query",
                        "description": "1 : aperçu du lot sans rien écrire.",
                        "schema": {
                            "type": "integer",
                            "enum": [
                                0,
                                1
                            ],
                            "default": 0
                        }
                    }
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/PushRequest"
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "Lot appliqué, ou rien à changer (refused = empty), ou aperçu (dry_run)",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "oneOf": [
                                        {
                                            "$ref": "#/components/schemas/PushResult"
                                        },
                                        {
                                            "$ref": "#/components/schemas/PushPreview"
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "400": {
                        "description": "Corps illisible, forme invalide ou lot vide (invalid_json, invalid_payload, empty_payload)",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "402": {
                        "description": "Solde de crédits insuffisant pour la rotation, rien n'est écrit (refused = credits)",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/PushResult"
                                }
                            }
                        }
                    },
                    "409": {
                        "description": "Rotation dépassée sans abonnement ou portefeuille trop grand (refused = rotation, too_large)",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/PushResult"
                                }
                            }
                        }
                    },
                    "403": {
                        "description": "Adresse e-mail du compte non confirmée (email_unconfirmed) : le portefeuille ne change pas avant la confirmation",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "413": {
                        "description": "Lot de plus de 10 000 fiches ou de plus de 4 Mo (too_many_entries, payload_too_large)",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "422": {
                        "description": "Lot de synchronisation contenant une ligne illisible (sync_invalid_lines), lignes listées dans invalid",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "429": {
                        "description": "Cadence dépassée pour ce jeton (rate_limited, 120 requêtes par minute), ou portefeuille sans abonnement déjà modifié 5 fois en 24 heures (free_daily_limit)",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        },
                        "headers": {
                            "Retry-After": {
                                "description": "Délai avant nouvel essai, en secondes.",
                                "schema": {
                                    "type": "integer"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/companies/{reference}": {
            "get": {
                "operationId": "getCompany",
                "summary": "Une fiche active par sa référence",
                "tags": [
                    "Portefeuille"
                ],
                "description": "Sans abonnement, alert_level, open_events et checked_at valent null.",
                "parameters": [
                    {
                        "name": "reference",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string",
                            "maxLength": 64
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Fiche",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "required": [
                                        "company"
                                    ],
                                    "properties": {
                                        "company": {
                                            "$ref": "#/components/schemas/Company"
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "404": {
                        "description": "Aucune fiche active ne porte cette référence (unknown_reference)",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "429": {
                        "$ref": "#/components/responses/RateLimited"
                    }
                }
            },
            "delete": {
                "operationId": "removeCompany",
                "summary": "Retirer une fiche par sa référence",
                "tags": [
                    "Portefeuille"
                ],
                "parameters": [
                    {
                        "name": "reference",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string",
                            "maxLength": 64
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Fiche retirée",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "required": [
                                        "removed",
                                        "reference"
                                    ],
                                    "properties": {
                                        "removed": {
                                            "type": "boolean",
                                            "const": true
                                        },
                                        "reference": {
                                            "type": "string"
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "404": {
                        "description": "Aucune fiche active ne porte cette référence (unknown_reference)",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "429": {
                        "$ref": "#/components/responses/RateLimited"
                    }
                }
            }
        },
        "/events": {
            "get": {
                "operationId": "listEvents",
                "summary": "Fil des événements, du plus récent au plus ancien",
                "tags": [
                    "Événements"
                ],
                "parameters": [
                    {
                        "name": "all",
                        "in": "query",
                        "description": "1 : tous les événements, acquittés compris.",
                        "schema": {
                            "type": "integer",
                            "enum": [
                                0,
                                1
                            ],
                            "default": 0
                        }
                    },
                    {
                        "name": "limit",
                        "in": "query",
                        "schema": {
                            "type": "integer",
                            "minimum": 1,
                            "maximum": 500,
                            "default": 100
                        }
                    },
                    {
                        "name": "offset",
                        "in": "query",
                        "schema": {
                            "type": "integer",
                            "minimum": 0,
                            "default": 0
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Page d'événements",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/EventList"
                                }
                            }
                        }
                    },
                    "403": {
                        "description": "Abonnement requis (subscription_required)",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "429": {
                        "$ref": "#/components/responses/RateLimited"
                    }
                }
            }
        },
        "/events/{uuid}": {
            "get": {
                "operationId": "getEvent",
                "summary": "Un événement par son identifiant",
                "tags": [
                    "Événements"
                ],
                "parameters": [
                    {
                        "name": "uuid",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string",
                            "pattern": "^[0-9a-f]{32}$"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Événement",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "required": [
                                        "event"
                                    ],
                                    "properties": {
                                        "event": {
                                            "$ref": "#/components/schemas/Event"
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "403": {
                        "description": "Abonnement requis (subscription_required)",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "404": {
                        "description": "Événement inconnu (unknown_event)",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "429": {
                        "$ref": "#/components/responses/RateLimited"
                    }
                }
            }
        },
        "/events/{uuid}/ack": {
            "post": {
                "operationId": "acknowledgeEvent",
                "summary": "Acquitter un événement (idempotent)",
                "tags": [
                    "Événements"
                ],
                "parameters": [
                    {
                        "name": "uuid",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string",
                            "pattern": "^[0-9a-f]{32}$"
                        }
                    }
                ],
                "requestBody": {
                    "required": false,
                    "content": {
                        "application/json": {
                            "schema": {
                                "type": "object",
                                "properties": {
                                    "ack": {
                                        "type": "string",
                                        "enum": [
                                            "seen",
                                            "accepted"
                                        ],
                                        "default": "seen"
                                    }
                                }
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "Événement acquitté",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "required": [
                                        "event"
                                    ],
                                    "properties": {
                                        "event": {
                                            "$ref": "#/components/schemas/Event"
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "400": {
                        "description": "Valeur d'acquittement invalide (invalid_ack)",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "403": {
                        "description": "Abonnement requis (subscription_required)",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "404": {
                        "description": "Événement inconnu (unknown_event)",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "429": {
                        "$ref": "#/components/responses/RateLimited"
                    }
                }
            }
        }
    },
    "webhooks": {
        "monitoring.event.detected": {
            "post": {
                "summary": "Un événement vient d'être détecté sur une fiche suivie",
                "description": "Corps mince : relisez le détail par GET /events/{uuid}. Répondez 2xx en moins de dix secondes ; sans réponse 2xx, neuf tentatives sur environ trois jours, puis l'adresse est désactivée.",
                "parameters": [
                    {
                        "name": "TierSafe-Event",
                        "in": "header",
                        "required": true,
                        "schema": {
                            "type": "string",
                            "enum": [
                                "monitoring.event.detected"
                            ]
                        }
                    },
                    {
                        "name": "TierSafe-Delivery",
                        "in": "header",
                        "required": true,
                        "description": "Identifiant de l'envoi, pour écarter un doublon (livraison au moins une fois).",
                        "schema": {
                            "type": "string",
                            "pattern": "^[0-9a-f]{32}$"
                        }
                    },
                    {
                        "name": "TierSafe-Signature",
                        "in": "header",
                        "required": true,
                        "description": "t=<horodatage Unix>,v1=<HMAC-SHA256 hexadécimal de « t.corps »>[,v1=...] ; deux v1 pendant une rotation de secret.",
                        "schema": {
                            "type": "string"
                        }
                    }
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/WebhookEvent"
                            }
                        }
                    }
                },
                "responses": {
                    "2XX": {
                        "description": "Reçu ; le corps de la réponse est ignoré."
                    }
                }
            }
        },
        "webhook.test": {
            "post": {
                "summary": "Envoi de test, déclenché depuis l'espace Sentinelle",
                "parameters": [
                    {
                        "name": "TierSafe-Event",
                        "in": "header",
                        "required": true,
                        "schema": {
                            "type": "string",
                            "enum": [
                                "webhook.test"
                            ]
                        }
                    },
                    {
                        "name": "TierSafe-Delivery",
                        "in": "header",
                        "required": true,
                        "schema": {
                            "type": "string",
                            "pattern": "^[0-9a-f]{32}$"
                        }
                    },
                    {
                        "name": "TierSafe-Signature",
                        "in": "header",
                        "required": true,
                        "schema": {
                            "type": "string"
                        }
                    }
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/WebhookTest"
                            }
                        }
                    }
                },
                "responses": {
                    "2XX": {
                        "description": "Reçu."
                    }
                }
            }
        }
    },
    "components": {
        "securitySchemes": {
            "bearerAuth": {
                "type": "http",
                "scheme": "bearer",
                "bearerFormat": "ts_ suivi de 48 caractères hexadécimaux",
                "description": "Jeton créé dans l'espace Sentinelle, page API ; montré une fois."
            }
        },
        "responses": {
            "Unauthorized": {
                "description": "Jeton absent, inconnu ou révoqué (invalid_token)",
                "content": {
                    "application/json": {
                        "schema": {
                            "$ref": "#/components/schemas/Error"
                        }
                    }
                }
            },
            "RateLimited": {
                "description": "Cadence dépassée pour ce jeton (rate_limited) : 120 requêtes par minute",
                "content": {
                    "application/json": {
                        "schema": {
                            "$ref": "#/components/schemas/Error"
                        }
                    }
                },
                "headers": {
                    "Retry-After": {
                        "description": "Délai avant nouvel essai, en secondes.",
                        "schema": {
                            "type": "integer"
                        }
                    }
                }
            }
        },
        "schemas": {
            "Error": {
                "type": "object",
                "required": [
                    "code",
                    "detail"
                ],
                "properties": {
                    "code": {
                        "type": "string",
                        "enum": [
                            "invalid_token",
                            "rate_limited",
                            "invalid_json",
                            "invalid_payload",
                            "empty_payload",
                            "too_many_entries",
                            "payload_too_large",
                            "sync_invalid_lines",
                            "unknown_reference",
                            "unknown_event",
                            "invalid_ack",
                            "subscription_required",
                            "email_unconfirmed",
                            "free_daily_limit"
                        ]
                    },
                    "detail": {
                        "type": "string",
                        "description": "Message lisible, en français ; ne pas programmer dessus."
                    },
                    "invalid": {
                        "type": "array",
                        "items": {
                            "$ref": "#/components/schemas/InvalidLine"
                        },
                        "description": "Présent avec sync_invalid_lines."
                    },
                    "duplicates": {
                        "type": "array",
                        "items": {
                            "$ref": "#/components/schemas/DuplicateLine"
                        },
                        "description": "Présent avec sync_invalid_lines."
                    }
                }
            },
            "Subscription": {
                "type": "object",
                "required": [
                    "subscribed",
                    "quota",
                    "followed",
                    "over_quota",
                    "coverage_end",
                    "rotation",
                    "credit_balance"
                ],
                "properties": {
                    "subscribed": {
                        "type": "boolean"
                    },
                    "quota": {
                        "type": "integer",
                        "description": "Fiches couvertes par le palier (0 sans abonnement)."
                    },
                    "followed": {
                        "type": "integer"
                    },
                    "over_quota": {
                        "type": "integer",
                        "description": "Fiches au-delà du palier : gardées, non surveillées."
                    },
                    "coverage_end": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "format": "date-time"
                    },
                    "rotation": {
                        "type": "object",
                        "required": [
                            "allowance",
                            "used"
                        ],
                        "properties": {
                            "allowance": {
                                "type": "integer"
                            },
                            "used": {
                                "type": "integer"
                            }
                        }
                    },
                    "credit_balance": {
                        "type": "integer"
                    }
                }
            },
            "CompanyInput": {
                "type": "object",
                "description": "Au moins un identifiant : siren, siret ou vat. Champs textuels uniquement.",
                "properties": {
                    "reference": {
                        "type": "string",
                        "maxLength": 64,
                        "description": "Référence client, unique dans le portefeuille ; vide, elle prend l'identifiant le plus précis."
                    },
                    "name": {
                        "type": "string",
                        "maxLength": 255
                    },
                    "siren": {
                        "type": "string"
                    },
                    "siret": {
                        "type": "string"
                    },
                    "vat": {
                        "type": "string"
                    },
                    "platform": {
                        "type": "string",
                        "description": "Plateforme agréée de réception."
                    },
                    "routing": {
                        "type": "string",
                        "description": "Identifiant de routage."
                    },
                    "address": {
                        "type": "string",
                        "maxLength": 255,
                        "description": "Adresse postale (voie), facultative : normalisée par la Base Adresse Nationale et comparée au répertoire SIRENE."
                    },
                    "postal_code": {
                        "type": "string",
                        "description": "Code postal."
                    },
                    "city": {
                        "type": "string",
                        "maxLength": 255,
                        "description": "Commune."
                    },
                    "iban": {
                        "type": "string",
                        "description": "IBAN du tiers, facultatif : structure, clé et cohérence des pays contrôlées, partage entre tiers du portefeuille signalé."
                    },
                    "bic": {
                        "type": "string",
                        "description": "BIC du tiers."
                    },
                    "email": {
                        "type": "string",
                        "format": "email",
                        "maxLength": 180,
                        "description": "Adresse e-mail de contact du tiers (une seule). Une adresse mal formée est écartée et signalée en anomalie."
                    }
                },
                "additionalProperties": true
            },
            "PushRequest": {
                "type": "object",
                "required": [
                    "companies"
                ],
                "properties": {
                    "mode": {
                        "type": "string",
                        "enum": [
                            "merge",
                            "sync"
                        ],
                        "default": "merge"
                    },
                    "companies": {
                        "type": "array",
                        "minItems": 1,
                        "maxItems": 10000,
                        "items": {
                            "$ref": "#/components/schemas/CompanyInput"
                        }
                    }
                }
            },
            "InvalidLine": {
                "type": "object",
                "required": [
                    "index",
                    "reason",
                    "reference"
                ],
                "properties": {
                    "index": {
                        "type": "integer",
                        "description": "Rang de la fiche dans le lot, à partir de 1."
                    },
                    "reason": {
                        "type": "string",
                        "enum": [
                            "field",
                            "no_identifier",
                            "siren",
                            "siret",
                            "vat"
                        ]
                    },
                    "reference": {
                        "type": [
                            "string",
                            "null"
                        ]
                    }
                }
            },
            "DuplicateLine": {
                "type": "object",
                "required": [
                    "index",
                    "reference"
                ],
                "properties": {
                    "index": {
                        "type": "integer"
                    },
                    "reference": {
                        "type": [
                            "string",
                            "null"
                        ]
                    }
                }
            },
            "Rotation": {
                "type": "object",
                "properties": {
                    "allowance": {
                        "type": "integer"
                    },
                    "used": {
                        "type": "integer"
                    },
                    "additions": {
                        "type": "integer"
                    },
                    "extra_credits": {
                        "type": "integer"
                    }
                }
            },
            "PushSummary": {
                "type": "object",
                "properties": {
                    "refused": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "enum": [
                            "rotation",
                            "credits",
                            "too_large",
                            "empty",
                            null
                        ]
                    },
                    "active_before": {
                        "type": "integer"
                    },
                    "active_after": {
                        "type": "integer"
                    },
                    "limit": {
                        "type": "integer"
                    },
                    "quota": {
                        "type": "integer"
                    },
                    "over_quota": {
                        "type": "integer"
                    },
                    "subscribed": {
                        "type": "boolean"
                    },
                    "rotation": {
                        "$ref": "#/components/schemas/Rotation"
                    },
                    "balance": {
                        "type": "integer"
                    },
                    "counts": {
                        "type": "object",
                        "additionalProperties": {
                            "type": "integer"
                        }
                    }
                }
            },
            "PushResult": {
                "type": "object",
                "required": [
                    "applied",
                    "refused",
                    "summary",
                    "invalid",
                    "duplicates"
                ],
                "properties": {
                    "applied": {
                        "type": "boolean"
                    },
                    "refused": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "enum": [
                            "rotation",
                            "credits",
                            "too_large",
                            "empty",
                            null
                        ]
                    },
                    "summary": {
                        "$ref": "#/components/schemas/PushSummary"
                    },
                    "invalid": {
                        "type": "array",
                        "items": {
                            "$ref": "#/components/schemas/InvalidLine"
                        }
                    },
                    "duplicates": {
                        "type": "array",
                        "items": {
                            "$ref": "#/components/schemas/DuplicateLine"
                        }
                    }
                }
            },
            "PushPreview": {
                "type": "object",
                "required": [
                    "dry_run",
                    "summary",
                    "invalid",
                    "duplicates"
                ],
                "properties": {
                    "dry_run": {
                        "type": "boolean",
                        "const": true
                    },
                    "summary": {
                        "$ref": "#/components/schemas/PushSummary"
                    },
                    "invalid": {
                        "type": "array",
                        "items": {
                            "$ref": "#/components/schemas/InvalidLine"
                        }
                    },
                    "duplicates": {
                        "type": "array",
                        "items": {
                            "$ref": "#/components/schemas/DuplicateLine"
                        }
                    }
                }
            },
            "Company": {
                "type": "object",
                "required": [
                    "uuid",
                    "reference",
                    "alert_level",
                    "awaiting_baseline",
                    "open_events",
                    "added_at",
                    "checked_at"
                ],
                "properties": {
                    "uuid": {
                        "type": "string"
                    },
                    "reference": {
                        "type": "string"
                    },
                    "name": {
                        "type": [
                            "string",
                            "null"
                        ]
                    },
                    "siren": {
                        "type": [
                            "string",
                            "null"
                        ]
                    },
                    "siret": {
                        "type": [
                            "string",
                            "null"
                        ]
                    },
                    "vat": {
                        "type": [
                            "string",
                            "null"
                        ]
                    },
                    "platform": {
                        "type": [
                            "string",
                            "null"
                        ]
                    },
                    "routing": {
                        "type": [
                            "string",
                            "null"
                        ]
                    },
                    "address": {
                        "type": [
                            "string",
                            "null"
                        ]
                    },
                    "postal_code": {
                        "type": [
                            "string",
                            "null"
                        ]
                    },
                    "city": {
                        "type": [
                            "string",
                            "null"
                        ]
                    },
                    "iban": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "description": "IBAN tel que fourni (normalisé)."
                    },
                    "bic": {
                        "type": [
                            "string",
                            "null"
                        ]
                    },
                    "email": {
                        "type": [
                            "string",
                            "null"
                        ]
                    },
                    "alert_level": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "enum": [
                            "none",
                            "watch",
                            "critical",
                            null
                        ],
                        "description": "null sans abonnement."
                    },
                    "awaiting_baseline": {
                        "type": "boolean"
                    },
                    "open_events": {
                        "type": [
                            "integer",
                            "null"
                        ],
                        "description": "null sans abonnement."
                    },
                    "added_at": {
                        "type": "string",
                        "format": "date-time"
                    },
                    "checked_at": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "format": "date-time",
                        "description": "null sans abonnement."
                    },
                    "anomalies": {
                        "type": [
                            "array",
                            "null"
                        ],
                        "items": {
                            "$ref": "#/components/schemas/Anomaly"
                        },
                        "description": "Anomalies de la fiche : les contrôles de la vérification de fichier (identifiants, TVA, raison sociale, routage, coordonnées bancaires, adresse, conflits entre fiches du portefeuille), faits quand la fiche entre ou change. null sans abonnement."
                    }
                }
            },
            "Anomaly": {
                "type": "object",
                "required": [
                    "code",
                    "severity",
                    "params"
                ],
                "properties": {
                    "code": {
                        "type": "string",
                        "description": "Code stable de l'anomalie (liste dans la documentation). Ignorez un code inconnu : la liste peut s'allonger."
                    },
                    "severity": {
                        "type": "string",
                        "enum": [
                            "blocking",
                            "review",
                            "info"
                        ]
                    },
                    "params": {
                        "type": "object",
                        "additionalProperties": {
                            "type": [
                                "string",
                                "integer"
                            ]
                        },
                        "description": "Valeurs du message (valeur écartée, numéro attendu, dénomination officielle, références des fiches en conflit...). Jamais d'IBAN."
                    }
                }
            },
            "CompanyList": {
                "type": "object",
                "required": [
                    "companies",
                    "total",
                    "limit",
                    "offset"
                ],
                "properties": {
                    "companies": {
                        "type": "array",
                        "items": {
                            "$ref": "#/components/schemas/Company"
                        }
                    },
                    "total": {
                        "type": "integer"
                    },
                    "limit": {
                        "type": "integer"
                    },
                    "offset": {
                        "type": "integer"
                    }
                }
            },
            "Event": {
                "type": "object",
                "required": [
                    "uuid",
                    "type",
                    "severity",
                    "source",
                    "detected_at"
                ],
                "properties": {
                    "uuid": {
                        "type": "string"
                    },
                    "type": {
                        "type": "string",
                        "enum": [
                            "proceeding",
                            "proceeding_closed",
                            "ceased",
                            "reactivated",
                            "establishment_closed",
                            "establishment_reopened",
                            "name_changed",
                            "head_office_moved",
                            "sirene_missing",
                            "vat_invalid",
                            "vat_valid",
                            "platform_removed",
                            "platform_registered",
                            "peppol_reachable",
                            "peppol_operator",
                            "management_changed",
                            "registry_changed",
                            "directory_reachable",
                            "directory_unreachable",
                            "directory_address_changed",
                            "platform_mismatch",
                            "address_mismatch"
                        ],
                        "description": "De nouveaux types peuvent apparaître."
                    },
                    "severity": {
                        "type": "string",
                        "enum": [
                            "critical",
                            "info",
                            "good"
                        ]
                    },
                    "source": {
                        "type": "string",
                        "enum": [
                            "sirene",
                            "bodacc",
                            "tva",
                            "pa",
                            "peppol"
                        ]
                    },
                    "company_reference": {
                        "type": [
                            "string",
                            "null"
                        ]
                    },
                    "company_name": {
                        "type": [
                            "string",
                            "null"
                        ]
                    },
                    "payload": {
                        "type": "object",
                        "description": "Détail propre au type (valeurs avant/après, nature du jugement, opérateur Peppol...)."
                    },
                    "source_date": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "format": "date"
                    },
                    "source_version": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "format": "date-time"
                    },
                    "detected_at": {
                        "type": "string",
                        "format": "date-time"
                    },
                    "acknowledged_at": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "format": "date-time"
                    },
                    "acknowledgement": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "enum": [
                            "seen",
                            "accepted",
                            null
                        ]
                    }
                }
            },
            "EventList": {
                "type": "object",
                "required": [
                    "events",
                    "open_only",
                    "total",
                    "limit",
                    "offset"
                ],
                "properties": {
                    "events": {
                        "type": "array",
                        "items": {
                            "$ref": "#/components/schemas/Event"
                        }
                    },
                    "open_only": {
                        "type": "boolean"
                    },
                    "total": {
                        "type": "integer"
                    },
                    "limit": {
                        "type": "integer"
                    },
                    "offset": {
                        "type": "integer"
                    }
                }
            },
            "WebhookEvent": {
                "type": "object",
                "required": [
                    "id",
                    "type",
                    "created_at",
                    "data"
                ],
                "properties": {
                    "id": {
                        "type": "string",
                        "description": "Identifiant de l'envoi, identique à l'en-tête TierSafe-Delivery."
                    },
                    "type": {
                        "type": "string",
                        "const": "monitoring.event.detected"
                    },
                    "created_at": {
                        "type": "string",
                        "format": "date-time"
                    },
                    "data": {
                        "type": "object",
                        "required": [
                            "event"
                        ],
                        "properties": {
                            "event": {
                                "type": "object",
                                "required": [
                                    "uuid",
                                    "type",
                                    "severity",
                                    "source",
                                    "detected_at",
                                    "url"
                                ],
                                "properties": {
                                    "uuid": {
                                        "type": "string"
                                    },
                                    "type": {
                                        "type": "string",
                                        "enum": [
                                            "proceeding",
                                            "proceeding_closed",
                                            "ceased",
                                            "reactivated",
                                            "establishment_closed",
                                            "establishment_reopened",
                                            "name_changed",
                                            "head_office_moved",
                                            "sirene_missing",
                                            "vat_invalid",
                                            "vat_valid",
                                            "platform_removed",
                                            "platform_registered",
                                            "peppol_reachable",
                                            "peppol_operator",
                                            "management_changed",
                                            "registry_changed",
                                            "directory_reachable",
                                            "directory_unreachable",
                                            "directory_address_changed",
                                            "platform_mismatch",
                                            "address_mismatch"
                                        ]
                                    },
                                    "severity": {
                                        "type": "string",
                                        "enum": [
                                            "critical",
                                            "info",
                                            "good"
                                        ]
                                    },
                                    "source": {
                                        "type": "string",
                                        "enum": [
                                            "sirene",
                                            "bodacc",
                                            "tva",
                                            "pa",
                                            "peppol"
                                        ]
                                    },
                                    "company_reference": {
                                        "type": [
                                            "string",
                                            "null"
                                        ]
                                    },
                                    "source_date": {
                                        "type": [
                                            "string",
                                            "null"
                                        ],
                                        "format": "date"
                                    },
                                    "detected_at": {
                                        "type": "string",
                                        "format": "date-time"
                                    },
                                    "url": {
                                        "type": "string",
                                        "format": "uri",
                                        "description": "GET de l'événement dans l'API."
                                    }
                                }
                            }
                        }
                    }
                }
            },
            "WebhookTest": {
                "type": "object",
                "required": [
                    "id",
                    "type",
                    "created_at",
                    "data"
                ],
                "properties": {
                    "id": {
                        "type": "string"
                    },
                    "type": {
                        "type": "string",
                        "const": "webhook.test"
                    },
                    "created_at": {
                        "type": "string",
                        "format": "date-time"
                    },
                    "data": {
                        "type": "object",
                        "properties": {
                            "message": {
                                "type": "string"
                            }
                        }
                    }
                }
            }
        }
    }
}