{
  "openapi": "3.0.3",
  "info": {
    "title": "Joute API",
    "description": "API JSON publique et gratuite du catalogue d'outils IA Joute. Pas d'auth, CORS open, cache 1h. Credit obligatoire : Source : Joute (https://joute.io).",
    "version": "1.0.0",
    "contact": {
      "name": "Joute",
      "url": "https://joute.io/api"
    },
    "license": {
      "name": "Données libres, credit obligatoire",
      "url": "https://joute.io/mentions-legales"
    }
  },
  "servers": [
    {
      "url": "https://joute.io/api/v1",
      "description": "Production"
    }
  ],
  "paths": {
    "/tools": {
      "get": {
        "summary": "Liste tous les outils IA",
        "operationId": "listTools",
        "parameters": [
          {
            "name": "page",
            "in": "query",
            "schema": { "type": "integer", "default": 1 }
          },
          {
            "name": "limit",
            "in": "query",
            "schema": { "type": "integer", "default": 50, "maximum": 200 }
          },
          {
            "name": "category",
            "in": "query",
            "schema": { "type": "string" },
            "description": "Slug catégorie : code, chat, image, video, voix, agents..."
          },
          {
            "name": "score_min",
            "in": "query",
            "schema": { "type": "number" }
          },
          {
            "name": "obsolescence_max",
            "in": "query",
            "schema": { "type": "number" }
          },
          {
            "name": "sort",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": ["score_desc", "score_asc", "name_asc", "name_desc"]
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Liste paginée d'outils",
            "headers": {
              "X-Total-Count": { "schema": { "type": "integer" } }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": { "$ref": "#/components/schemas/ToolItem" }
                    },
                    "meta": { "$ref": "#/components/schemas/PaginationMeta" }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/tools/{slug}": {
      "get": {
        "summary": "Détail d'un outil",
        "operationId": "getTool",
        "parameters": [
          {
            "name": "slug",
            "in": "path",
            "required": true,
            "schema": { "type": "string" }
          }
        ],
        "responses": {
          "200": {
            "description": "Fiche outil",
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ToolItem" }
              }
            }
          },
          "404": {
            "description": "Outil introuvable",
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/Error" }
              }
            }
          }
        }
      }
    },
    "/comparatifs": {
      "get": {
        "summary": "Liste les comparatifs publiés",
        "operationId": "listComparatifs",
        "parameters": [
          {
            "name": "page",
            "in": "query",
            "schema": { "type": "integer", "default": 1 }
          },
          {
            "name": "limit",
            "in": "query",
            "schema": { "type": "integer", "default": 50, "maximum": 200 }
          },
          { "name": "category", "in": "query", "schema": { "type": "string" } }
        ],
        "responses": {
          "200": { "description": "Liste paginée de comparatifs" }
        }
      }
    },
    "/comparatifs/{slug}": {
      "get": {
        "summary": "Détail d'un comparatif",
        "operationId": "getComparatif",
        "parameters": [
          {
            "name": "slug",
            "in": "path",
            "required": true,
            "schema": { "type": "string" }
          }
        ],
        "responses": {
          "200": {
            "description": "Fiche comparatif avec scores des deux outils"
          },
          "404": {
            "description": "Comparatif introuvable",
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/Error" }
              }
            }
          }
        }
      }
    },
    "/pricing": {
      "get": {
        "summary": "Tous les prix actuels",
        "operationId": "listPricing",
        "parameters": [
          {
            "name": "page",
            "in": "query",
            "schema": { "type": "integer", "default": 1 }
          },
          {
            "name": "limit",
            "in": "query",
            "schema": { "type": "integer", "default": 50, "maximum": 200 }
          },
          { "name": "category", "in": "query", "schema": { "type": "string" } }
        ],
        "responses": {
          "200": { "description": "Liste prix" }
        }
      }
    },
    "/pricing/{slug}": {
      "get": {
        "summary": "Prix courant et historique d'un outil",
        "operationId": "getPricing",
        "parameters": [
          {
            "name": "slug",
            "in": "path",
            "required": true,
            "schema": { "type": "string" }
          }
        ],
        "responses": {
          "200": { "description": "Prix et historique" },
          "404": { "description": "Outil introuvable" }
        }
      }
    },
    "/cimetiere": {
      "get": {
        "summary": "Outils morts, acquis ou dépréciés",
        "operationId": "listCimetiere",
        "parameters": [
          {
            "name": "page",
            "in": "query",
            "schema": { "type": "integer", "default": 1 }
          },
          {
            "name": "limit",
            "in": "query",
            "schema": { "type": "integer", "default": 50, "maximum": 200 }
          },
          { "name": "category", "in": "query", "schema": { "type": "string" } },
          {
            "name": "reason",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": ["mort", "acquis", "deprecie", "pivot", "absorbe"]
            }
          }
        ],
        "responses": {
          "200": { "description": "Liste outils retirés" }
        }
      }
    },
    "/categories": {
      "get": {
        "summary": "Catégories d'outils avec stats",
        "operationId": "listCategories",
        "responses": {
          "200": { "description": "Liste catégories" }
        }
      }
    },
    "/stats": {
      "get": {
        "summary": "Méta-statistiques globales",
        "operationId": "getStats",
        "responses": {
          "200": { "description": "Stats agrégées" }
        }
      }
    }
  },
  "components": {
    "schemas": {
      "ToolItem": {
        "type": "object",
        "properties": {
          "slug": { "type": "string" },
          "name": { "type": "string" },
          "domain": { "type": "string" },
          "category": { "type": "string" },
          "icp": {
            "type": "string",
            "enum": ["vibe-coder", "agentic-engineer", "mixte"]
          },
          "pricing": {
            "type": "string",
            "enum": ["gratuit", "freemium", "payant"]
          },
          "price": { "type": "string" },
          "score": { "type": "number", "nullable": true },
          "verifiability": { "type": "number", "nullable": true },
          "tagline": { "type": "string" },
          "canonical_url": { "type": "string", "format": "uri" },
          "avis_url": { "type": "string", "format": "uri", "nullable": true },
          "alternatives_url": { "type": "string", "format": "uri" },
          "updated_at": { "type": "string", "format": "date" }
        }
      },
      "PaginationMeta": {
        "type": "object",
        "properties": {
          "total": { "type": "integer" },
          "page": { "type": "integer" },
          "limit": { "type": "integer" },
          "pages": { "type": "integer" }
        }
      },
      "Error": {
        "type": "object",
        "properties": {
          "error": { "type": "string" }
        }
      }
    }
  }
}
