{
  "openapi": "3.0.3",
  "info": {
    "title": "Company Belgium API",
    "description": "API pour rechercher des entreprises belges via la base de données KBO (Banque-Carrefour des Entreprises). Nécessite une authentification par clé API.",
    "version": "1.0.0",
    "contact": {
      "name": "API Support"
    }
  },
  "servers": [
    {
      "url": "http://localhost:3000",
      "description": "Development server"
    },
    {
      "url": "https://companybelgium.be",
      "description": "Production server"
    }
  ],
  "security": [
    {
      "ApiKeyAuth": []
    }
  ],
  "paths": {
    "/api/openapi": {
      "get": {
        "summary": "Documentation OpenAPI",
        "description": "Retourne la spécification OpenAPI complète au format JSON",
        "operationId": "getOpenAPISpec",
        "tags": ["System"],
        "security": [],
        "responses": {
          "200": {
            "description": "Spécification OpenAPI",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "description": "Spécification OpenAPI 3.0.3"
                }
              }
            }
          }
        }
      }
    },
    "/api/health": {
      "get": {
        "summary": "Health Check",
        "description": "Vérifie l'état de santé de l'API et ses services",
        "operationId": "getHealth",
        "tags": ["System"],
        "responses": {
          "200": {
            "description": "État de santé du système",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HealthResponse"
                },
                "example": {
                  "status": "ok",
                  "version": "1.0.0",
                  "timestamp": "2026-02-08T10:30:00.000Z",
                  "uptime": 3600.5,
                  "services": {
                    "kboPublicSearch": "operational"
                  },
                  "responseTime": 150
                }
              }
            }
          }
        }
      }
    },
    "/api/companies/search": {
      "get": {
        "summary": "Rechercher des entreprises",
        "description": "Recherche des entreprises belges par nom, code postal, ville ou code NACE",
        "operationId": "searchCompanies",
        "tags": ["Companies"],
        "parameters": [
          {
            "name": "name",
            "in": "query",
            "description": "Nom de l'entreprise à rechercher",
            "required": false,
            "schema": {
              "type": "string",
              "example": "Google Belgium"
            }
          },
          {
            "name": "zipCode",
            "in": "query",
            "description": "Code postal (alias: zipcode)",
            "required": false,
            "schema": {
              "type": "string",
              "example": "1000"
            }
          },
          {
            "name": "city",
            "in": "query",
            "description": "Ville",
            "required": false,
            "schema": {
              "type": "string",
              "example": "Bruxelles"
            }
          },
          {
            "name": "naceCode",
            "in": "query",
            "description": "Code NACE de l'activité (alias: nace)",
            "required": false,
            "schema": {
              "type": "string",
              "example": "62010"
            }
          },
          {
            "name": "page",
            "in": "query",
            "description": "Numéro de page pour la pagination",
            "required": false,
            "schema": {
              "type": "integer",
              "default": 1,
              "minimum": 1,
              "example": 1
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Résultats de recherche",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SearchAPIResponse"
                },
                "example": {
                  "success": true,
                  "data": {
                    "results": [
                      {
                        "enterpriseNumber": "0878.065.378",
                        "name": "Google Belgium",
                        "status": "Actif",
                        "type": "Personne morale",
                        "address": "Chaussée de Wavre 1945, 1160 Bruxelles",
                        "startDate": "01/01/2007"
                      }
                    ],
                    "totalResults": 1,
                    "currentPage": 1,
                    "totalPages": 1,
                    "searchParams": {
                      "name": "Google Belgium",
                      "page": 1
                    }
                  },
                  "timestamp": "2026-02-08T10:30:00.000Z",
                  "meta": {
                    "totalResults": 1,
                    "currentPage": 1,
                    "totalPages": 1,
                    "responseTime": 850
                  }
                }
              }
            }
          },
          "400": {
            "description": "Paramètres invalides",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "success": false,
                  "error": "Au moins un critere de recherche est requis: name, zipCode, city, ou naceCode",
                  "timestamp": "2026-02-08T10:30:00.000Z"
                }
              }
            }
          },
          "500": {
            "description": "Erreur serveur",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/api/companies/address": {
      "get": {
        "summary": "Rechercher des entreprises par adresse",
        "description": "Recherche des entreprises belges par code postal, nom de rue et numéro de maison. Les résultats peuvent également être téléchargés au format PDF via le lien fourni dans l'interface utilisateur.",
        "operationId": "searchCompaniesByAddress",
        "tags": ["Companies"],
        "parameters": [
          {
            "name": "postalCode",
            "in": "query",
            "description": "Code postal belge (4 chiffres)",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^\\d{4}$",
              "example": "1080"
            }
          },
          {
            "name": "street",
            "in": "query",
            "description": "Nom de la rue (sera converti en majuscules automatiquement)",
            "required": true,
            "schema": {
              "type": "string",
              "example": "RUE DE LA COLONNE"
            }
          },
          {
            "name": "houseNumber",
            "in": "query",
            "description": "Numéro de maison (optionnel, peut inclure des lettres comme 1A, 12B)",
            "required": false,
            "schema": {
              "type": "string",
              "example": "1A"
            }
          },
          {
            "name": "page",
            "in": "query",
            "description": "Numéro de la page pour la pagination (20 résultats par page)",
            "required": false,
            "schema": {
              "type": "integer",
              "default": 1,
              "minimum": 1,
              "example": 1
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Résultats de recherche par adresse",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {"$ref": "#/components/schemas/APIResponse"},
                    {
                      "type": "object",
                      "properties": {
                        "data": {
                          "$ref": "#/components/schemas/SearchResponse"
                        },
                        "meta": {
                          "type": "object",
                          "properties": {
                            "totalResults": {"type": "integer"},
                            "currentPage": {"type": "integer"},
                            "totalPages": {"type": "integer"},
                            "responseTime": {"type": "integer"}
                          }
                        }
                      }
                    }
                  ]
                },
                "example": {
                  "success": true,
                  "data": {
                    "results": [
                      {
                        "enterpriseNumber": "0631.880.764",
                        "name": "25 RUE DE LA GLACIERE",
                        "status": "Actif",
                        "type": "ENT PM",
                        "address": "Rue de la Colonne 1A, 1080 Molenbeek-Saint-Jean"
                      },
                      {
                        "enterpriseNumber": "0780.749.436",
                        "name": "A & R Beauté",
                        "status": "Actif",
                        "type": "ENT PM",
                        "address": "Rue de la Colonne 1A, 1080 Molenbeek-Saint-Jean"
                      }
                    ],
                    "totalResults": 440,
                    "currentPage": 1,
                    "totalPages": 22
                  },
                  "timestamp": "2026-02-11T10:30:00.000Z",
                  "meta": {
                    "totalResults": 440,
                    "currentPage": 1,
                    "totalPages": 22,
                    "responseTime": 1250
                  }
                }
              }
            }
          },
          "400": {
            "description": "Paramètres de recherche invalides",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "success": false,
                  "error": "Missing required parameter: postalCode",
                  "timestamp": "2026-02-11T10:30:00.000Z"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/UnauthorizedError"
          },
          "502": {
            "$ref": "#/components/responses/BadGatewayError"
          }
        }
      }
    },
    "/api/stats": {
      "get": {
        "summary": "Statistiques d'utilisation",
        "description": "Récupère les statistiques d'utilisation des clés API",
        "operationId": "getStats",
        "tags": ["Statistics"],
        "security": [{"SessionAuth": []}],
        "responses": {
          "200": {
            "description": "Statistiques",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "totalRequests": {"type": "integer"},
                    "requestsThisMonth": {"type": "integer"},
                    "avgResponseTime": {"type": "integer", "nullable": true},
                    "successRate": {"type": "integer", "nullable": true}
                  }
                }
              }
            }
          }
        }
      }
    },
    "/api/companies/{id}": {
      "get": {
        "summary": "Obtenir les détails d'une entreprise",
        "description": "Récupère les informations détaillées d'une entreprise par son numéro d'entreprise",
        "operationId": "getCompanyById",
        "tags": ["Companies"],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "description": "Numéro d'entreprise (format: 0123.456.789 ou BE0123456789)",
            "required": true,
            "schema": {
              "type": "string",
              "example": "0878.065.378"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Détails de l'entreprise",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CompanyDetailAPIResponse"
                },
                "example": {
                  "success": true,
                  "data": {
                    "enterpriseNumber": "0878.065.378",
                    "name": "Google Belgium",
                    "status": "Actif",
                    "type": "Personne morale",
                    "juridicalForm": "Société à responsabilité limitée",
                    "startDate": "01/01/2007",
                    "address": "Chaussée de Wavre 1945, 1160 Bruxelles",
                    "phone": "+32 2 123 45 67",
                    "email": "info@google.be",
                    "website": "https://www.google.be",
                    "activities": [
                      {
                        "naceCode": "62010",
                        "description": "Programmation informatique",
                        "classification": "Activité principale"
                      }
                    ],
                    "establishments": [
                      {
                        "establishmentNumber": "2.123.456.789",
                        "name": "Siège d'exploitation",
                        "address": "Chaussée de Wavre 1945, 1160 Bruxelles",
                        "startDate": "01/01/2007"
                      }
                    ],
                    "functions": [
                      {
                        "functionType": "Administrateur",
                        "person": "John Doe",
                        "startDate": "01/01/2007"
                      }
                    ]
                  },
                  "timestamp": "2026-02-08T10:30:00.000Z",
                  "meta": {
                    "responseTime": 650
                  }
                }
              }
            }
          },
          "400": {
            "description": "Format de numéro invalide",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "success": false,
                  "error": "Format invalide. Utilisez le format: 0123.456.789 ou BE0123456789",
                  "timestamp": "2026-02-08T10:30:00.000Z"
                }
              }
            }
          },
          "404": {
            "description": "Entreprise non trouvée",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "success": false,
                  "error": "Aucune entreprise trouvee pour le numero 0123.456.789",
                  "timestamp": "2026-02-08T10:30:00.000Z",
                  "meta": {
                    "responseTime": 450
                  }
                }
              }
            }
          },
          "500": {
            "description": "Erreur serveur",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/api/peppol/check": {
      "get": {
        "summary": "Vérifier l'enregistrement Peppol",
        "description": "Vérifie si une entreprise belge est enregistrée sur le réseau Peppol pour la facturation électronique",
        "operationId": "checkPeppolRegistration",
        "tags": ["Peppol"],
        "parameters": [
          {
            "name": "vatNumber",
            "in": "query",
            "description": "Numéro de TVA belge (format: 1033022383 ou BE1033022383)",
            "required": true,
            "schema": {
              "type": "string",
              "example": "1033022383"
            }
          },
          {
            "name": "vat",
            "in": "query",
            "description": "Alias pour vatNumber",
            "required": false,
            "schema": {
              "type": "string",
              "example": "BE1033022383"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Résultat de la vérification Peppol",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {"$ref": "#/components/schemas/APIResponse"},
                    {
                      "type": "object",
                      "properties": {
                        "data": {
                          "$ref": "#/components/schemas/PeppolRegistration"
                        },
                        "meta": {
                          "type": "object",
                          "properties": {
                            "responseTime": {"type": "integer"}
                          }
                        }
                      }
                    }
                  ]
                },
                "examples": {
                  "registered": {
                    "summary": "Entreprise enregistrée sur Peppol",
                    "value": {
                      "success": true,
                      "data": {
                        "isRegistered": true,
                        "entityName": "Espero-Soft Informatiques",
                        "country": "Belgium",
                        "countryCode": "BE",
                        "registrationDate": "Jan 16, 2026",
                        "identifiers": [
                          {
                            "scheme": "iso6523-actorid-upis",
                            "value": "0208:1033022383"
                          },
                          {
                            "scheme": "iso6523-actorid-upis",
                            "value": "9925:be1033022383"
                          }
                        ],
                        "documentTypes": [
                          "Peppol Invoice Response transaction 3.0",
                          "Peppol Message Level Response transaction 3.0",
                          "Peppol BIS Billing UBL Credit Note V3",
                          "UBL.BE Credit Note 3.0",
                          "Peppol BIS Billing UBL Invoice V3",
                          "UBL.BE Invoice 3.0"
                        ],
                        "smpUrl": "https://smp.codabox.com",
                        "endpointUrl": "https://peppol.codabox.com/peppol/as4"
                      },
                      "timestamp": "2026-02-11T22:00:00.000Z",
                      "meta": {
                        "responseTime": 1250
                      }
                    }
                  },
                  "notRegistered": {
                    "summary": "Entreprise non enregistrée sur Peppol",
                    "value": {
                      "success": true,
                      "data": {
                        "isRegistered": false
                      },
                      "timestamp": "2026-02-11T22:00:00.000Z",
                      "meta": {
                        "responseTime": 850
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Paramètre manquant",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "success": false,
                  "error": "Paramètre manquant: 'vatNumber' ou 'vat' requis (numéro de TVA belge)",
                  "timestamp": "2026-02-11T22:00:00.000Z"
                }
              }
            }
          },
          "401": {
            "description": "Authentification requise",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "502": {
            "description": "Erreur du service Peppol en amont",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "success": false,
                  "error": "Erreur lors de la vérification Peppol",
                  "timestamp": "2026-02-11T22:00:00.000Z"
                }
              }
            }
          }
        }
      }
    }
  },
  "components": {
    "schemas": {
      "HealthResponse": {
        "type": "object",
        "properties": {
          "status": {
            "type": "string",
            "enum": ["ok", "degraded", "down"],
            "description": "État général du système"
          },
          "version": {
            "type": "string",
            "description": "Version de l'API"
          },
          "timestamp": {
            "type": "string",
            "format": "date-time",
            "description": "Date et heure de la réponse"
          },
          "uptime": {
            "type": "number",
            "description": "Temps de fonctionnement en secondes"
          },
          "services": {
            "type": "object",
            "properties": {
              "kboPublicSearch": {
                "type": "string",
                "enum": ["operational", "degraded", "down", "unknown"],
                "description": "État du service KBO"
              }
            }
          },
          "responseTime": {
            "type": "number",
            "description": "Temps de réponse en millisecondes"
          }
        }
      },
      "CompanyResult": {
        "type": "object",
        "properties": {
          "enterpriseNumber": {
            "type": "string",
            "description": "Numéro d'entreprise unique"
          },
          "name": {
            "type": "string",
            "description": "Nom de l'entreprise"
          },
          "status": {
            "type": "string",
            "description": "Statut de l'entreprise (Actif, Inactif, etc.)"
          },
          "type": {
            "type": "string",
            "description": "Type d'entreprise (Personne morale, Personne physique, etc.)"
          },
          "address": {
            "type": "string",
            "description": "Adresse complète"
          },
          "startDate": {
            "type": "string",
            "description": "Date de début d'activité"
          }
        },
        "required": ["enterpriseNumber", "name", "status", "type"]
      },
      "Activity": {
        "type": "object",
        "properties": {
          "naceCode": {
            "type": "string",
            "description": "Code NACE de l'activité"
          },
          "description": {
            "type": "string",
            "description": "Description de l'activité"
          },
          "classification": {
            "type": "string",
            "description": "Classification de l'activité"
          }
        },
        "required": ["naceCode", "description"]
      },
      "Establishment": {
        "type": "object",
        "properties": {
          "establishmentNumber": {
            "type": "string",
            "description": "Numéro d'établissement"
          },
          "name": {
            "type": "string",
            "description": "Nom de l'établissement"
          },
          "address": {
            "type": "string",
            "description": "Adresse de l'établissement"
          },
          "startDate": {
            "type": "string",
            "description": "Date de début"
          }
        },
        "required": ["establishmentNumber"]
      },
      "CompanyFunction": {
        "type": "object",
        "properties": {
          "functionType": {
            "type": "string",
            "description": "Type de fonction (Administrateur, Gérant, etc.)"
          },
          "person": {
            "type": "string",
            "description": "Nom de la personne"
          },
          "startDate": {
            "type": "string",
            "description": "Date de début de la fonction"
          }
        },
        "required": ["functionType"]
      },
      "CompanyDetail": {
        "type": "object",
        "properties": {
          "enterpriseNumber": {
            "type": "string",
            "description": "Numéro d'entreprise unique"
          },
          "name": {
            "type": "string",
            "description": "Nom de l'entreprise"
          },
          "status": {
            "type": "string",
            "description": "Statut de l'entreprise"
          },
          "type": {
            "type": "string",
            "description": "Type d'entreprise"
          },
          "juridicalForm": {
            "type": "string",
            "description": "Forme juridique"
          },
          "startDate": {
            "type": "string",
            "description": "Date de début d'activité"
          },
          "address": {
            "type": "string",
            "description": "Adresse complète"
          },
          "phone": {
            "type": "string",
            "description": "Numéro de téléphone"
          },
          "email": {
            "type": "string",
            "description": "Adresse email"
          },
          "website": {
            "type": "string",
            "description": "Site web"
          },
          "activities": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Activity"
            },
            "description": "Liste des activités"
          },
          "establishments": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Establishment"
            },
            "description": "Liste des établissements"
          },
          "functions": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/CompanyFunction"
            },
            "description": "Liste des fonctions"
          }
        },
        "required": ["enterpriseNumber", "name", "status", "type"]
      },
      "SearchResponse": {
        "type": "object",
        "properties": {
          "results": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/CompanyResult"
            },
            "description": "Liste des résultats"
          },
          "totalResults": {
            "type": "integer",
            "description": "Nombre total de résultats"
          },
          "currentPage": {
            "type": "integer",
            "description": "Page actuelle"
          },
          "totalPages": {
            "type": "integer",
            "description": "Nombre total de pages"
          },
          "searchParams": {
            "type": "object",
            "description": "Paramètres de recherche utilisés"
          }
        },
        "required": ["results", "totalResults", "currentPage", "totalPages", "searchParams"]
      },
      "SearchAPIResponse": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean",
            "description": "Indique si la requête a réussi"
          },
          "data": {
            "$ref": "#/components/schemas/SearchResponse"
          },
          "timestamp": {
            "type": "string",
            "format": "date-time",
            "description": "Date et heure de la réponse"
          },
          "meta": {
            "type": "object",
            "properties": {
              "totalResults": {
                "type": "integer"
              },
              "currentPage": {
                "type": "integer"
              },
              "totalPages": {
                "type": "integer"
              },
              "responseTime": {
                "type": "number",
                "description": "Temps de réponse en millisecondes"
              }
            }
          }
        },
        "required": ["success", "timestamp"]
      },
      "CompanyDetailAPIResponse": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean",
            "description": "Indique si la requête a réussi"
          },
          "data": {
            "$ref": "#/components/schemas/CompanyDetail"
          },
          "timestamp": {
            "type": "string",
            "format": "date-time",
            "description": "Date et heure de la réponse"
          },
          "meta": {
            "type": "object",
            "properties": {
              "responseTime": {
                "type": "number",
                "description": "Temps de réponse en millisecondes"
              }
            }
          }
        },
        "required": ["success", "timestamp"]
      },
      "ErrorResponse": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean",
            "description": "Toujours false pour les erreurs"
          },
          "error": {
            "type": "string",
            "description": "Message d'erreur"
          },
          "timestamp": {
            "type": "string",
            "format": "date-time",
            "description": "Date et heure de la réponse"
          },
          "meta": {
            "type": "object",
            "properties": {
              "responseTime": {
                "type": "number",
                "description": "Temps de réponse en millisecondes"
              }
            }
          }
        },
        "required": ["success", "error", "timestamp"]
      }
    },
    "securitySchemes": {
      "ApiKeyAuth": {
        "type": "apiKey",
        "in": "header",
        "name": "X-API-Key",
        "description": "Clé publique API (format: pk_live_...)",
        "x-secret-header": {
          "name": "X-API-Secret",
          "description": "Clé secrète API (format: sk_live_...)"
        }
      }
    },
    "PeppolRegistration": {
      "type": "object",
      "properties": {
        "isRegistered": {
          "type": "boolean",
          "description": "Indique si l'entreprise est enregistrée sur le réseau Peppol"
        },
        "entityName": {
          "type": "string",
          "description": "Nom de l'entité enregistrée"
        },
        "country": {
          "type": "string",
          "description": "Pays d'enregistrement"
        },
        "countryCode": {
          "type": "string",
          "description": "Code pays ISO (BE, FR, NL, etc.)"
        },
        "registrationDate": {
          "type": "string",
          "description": "Date d'enregistrement sur Peppol"
        },
        "identifiers": {
          "type": "array",
          "items": {
            "type": "object",
            "properties": {
              "scheme": {
                "type": "string",
                "description": "Schéma d'identification (ex: iso6523-actorid-upis)"
              },
              "value": {
                "type": "string",
                "description": "Valeur de l'identifiant"
              }
            }
          },
          "description": "Liste des identifiants Peppol"
        },
        "documentTypes": {
          "type": "array",
          "items": {
            "type": "string"
          },
          "description": "Types de documents supportés (factures, etc.)"
        },
        "smpUrl": {
          "type": "string",
          "description": "URL du Service Metadata Publisher"
        },
        "endpointUrl": {
          "type": "string",
          "description": "URL du point de terminaison pour l'échange de documents"
        }
      },
      "required": ["isRegistered"]
    }
  },
  "tags": [
    {
      "name": "System",
      "description": "Endpoints système"
    },
    {
      "name": "Companies",
      "description": "Endpoints pour la recherche d'entreprises"
    },
    {
      "name": "Peppol",
      "description": "Vérification de l'enregistrement Peppol des entreprises belges"
    }
  ]
}
