33800 Docs

← Retour
{ "openapi": "3.0.3", "info": { "title": "Connectors Hub API", "description": "Hub centralisé pour authentification et communication avec APIs externes.\n\n## Connecteurs disponibles\n\n| Connecteur | Base URL | Documentation |\n|------------|----------|---------------|\n| **github** | https://api.github.com | [GitHub REST API](https://docs.github.com/en/rest) |\n| **mailjet** | https://api.mailjet.com/v3 | [Mailjet API](https://dev.mailjet.com/email/reference/) |\n| **o2switch** | https://yellow.o2switch.net:2083 | [cPanel UAPI](https://api.docs.cpanel.net/cpanel/introduction/) |\n| **linkedin** | https://api.linkedin.com | [LinkedIn API](https://learn.microsoft.com/en-us/linkedin/shared/integrations/people/profile-api) |\n\n## Authentification\n\n**Option 1: JWT (session)**\nUtilisez `/api/auth/login` pour obtenir un access_token JWT:\n```\nAuthorization: Bearer <access_token>\n```\n\n**Option 2: Clé API (programmatique)**\nCréez une clé via `POST /api/auth/api-keys`, puis utilisez:\n```\nX-API-Key: ck_live_xxx...\n```\nou\n```\nAuthorization: Bearer ck_live_xxx...\n```\n\n## Proxy Fetch\n\nL'endpoint principal est `POST /api/fetch` qui permet d'appeler n'importe quelle API externe via un connecteur configuré.\nL'authentification vers l'API externe est gérée automatiquement.\n\n## Exemples\n\n**GitHub - Lister ses repos:**\n```json\n{\n \"connector\": \"github\",\n \"method\": \"GET\",\n \"path\": \"/user/repos\"\n}\n```\n\n**Mailjet - Envoyer un email:**\n```json\n{\n \"connector\": \"mailjet\",\n \"method\": \"POST\",\n \"path\": \"/send\",\n \"body\": {\n \"Messages\": [{\n \"From\": {\"Email\": \"noreply@example.com\"},\n \"To\": [{\"Email\": \"user@example.com\"}],\n \"Subject\": \"Test\",\n \"TextPart\": \"Hello!\"\n }]\n }\n}\n```\n\n**O2switch - Lister les domaines:**\n```json\n{\n \"connector\": \"o2switch\",\n \"method\": \"GET\",\n \"path\": \"/execute/DomainInfo/list_domains\"\n}\n```\n\n**LinkedIn - Mon profil:**\n```json\n{\n \"connector\": \"linkedin\",\n \"method\": \"GET\",\n \"path\": \"/v2/userinfo\"\n}\n```\n", "version": "2.5.0" }, "tags": [ { "name": "fetch", "description": "🚀 Proxy fetch - Appeler des APIs externes" }, { "name": "auth", "description": "🔐 Authentification utilisateur" }, { "name": "connectors", "description": "⚙️ Gestion des connecteurs + schemas" }, { "name": "user", "description": "👤 Tokens utilisateur" }, { "name": "instances", "description": "📦 Instances multi-comptes" }, { "name": "ssh", "description": "🖥️ SSH - Commandes distantes" }, { "name": "audit", "description": "📋 Audit logs - Historique des actions" }, { "name": "endpoints", "description": "🔗 Gestion des endpoints + versioning" }, { "name": "health", "description": "💚 Health checks" } ], "components": { "securitySchemes": { "bearerAuth": { "type": "http", "scheme": "bearer", "bearerFormat": "JWT", "description": "JWT obtenu via /api/auth/login" }, "apiKeyAuth": { "type": "apiKey", "in": "header", "name": "X-API-Key", "description": "Clé API créée via POST /api/auth/api-keys" } }, "schemas": {} }, "paths": { "/health": { "get": { "responses": { "200": { "content": { "application/json": { "schema": { "type": "object", "properties": { "status": { "examples": [ "ok", "degraded" ], "type": "string" }, "service": { "type": "string" }, "version": { "type": "string" }, "database": { "examples": [ "connected", "disconnected" ], "type": "string" } }, "required": [ "status", "service", "version", "database" ] } }, "multipart/form-data": { "schema": { "type": "object", "properties": { "status": { "examples": [ "ok", "degraded" ], "type": "string" }, "service": { "type": "string" }, "version": { "type": "string" }, "database": { "examples": [ "connected", "disconnected" ], "type": "string" } }, "required": [ "status", "service", "version", "database" ] } }, "text/plain": { "schema": { "type": "object", "properties": { "status": { "examples": [ "ok", "degraded" ], "type": "string" }, "service": { "type": "string" }, "version": { "type": "string" }, "database": { "examples": [ "connected", "disconnected" ], "type": "string" } }, "required": [ "status", "service", "version", "database" ] } } } } }, "operationId": "getHealth", "summary": "Health check", "description": "Vérifie l'état du service et de la base de données", "tags": [ "health" ] } }, "/api/fetch": { "post": { "parameters": [], "responses": { "200": { "content": { "application/json": { "schema": { "type": "object", "properties": { "success": { "type": "boolean" }, "status": { "description": "HTTP status code de l'API externe", "type": "number" }, "data": { "description": "Réponse de l'API externe" }, "error": { "description": "Message d'erreur si échec", "type": "string" } }, "required": [ "success" ] } }, "multipart/form-data": { "schema": { "type": "object", "properties": { "success": { "type": "boolean" }, "status": { "description": "HTTP status code de l'API externe", "type": "number" }, "data": { "description": "Réponse de l'API externe" }, "error": { "description": "Message d'erreur si échec", "type": "string" } }, "required": [ "success" ] } }, "text/plain": { "schema": { "type": "object", "properties": { "success": { "type": "boolean" }, "status": { "description": "HTTP status code de l'API externe", "type": "number" }, "data": { "description": "Réponse de l'API externe" }, "error": { "description": "Message d'erreur si échec", "type": "string" } }, "required": [ "success" ] } } } } }, "operationId": "postApiFetch", "summary": "Proxy fetch vers API externe", "description": "Exécute une requête HTTP vers une API externe via un connecteur.\n\nL'authentification est gérée automatiquement selon le type du connecteur:\n- **bearer**: Header Authorization: Bearer <token>\n- **basic**: Header Authorization: Basic <base64>\n- **api_key**: Header X-API-Key ou paramètre selon config\n- **oauth2**: Token OAuth2 avec refresh automatique\n- **custom**: Format personnalisé (ex: cPanel)\n- **none**: Pas d'authentification (connecteurs publics)\n\n**Multi-comptes:** Utilisez le paramètre `instance` pour cibler une instance spécifique.\nExemple: `{\"connector\": \"jellyfin\", \"instance\": \"Jellyfin Famille\", ...}`\n\n**Connecteurs disponibles:** github, mailjet, o2switch, linkedin, jellyfin, ai-orchestrator, yolo, scraper, web-search\n\n**Scope requis (API Key):** `fetch`", "security": [ { "bearerAuth": [] }, { "apiKeyAuth": [] } ], "tags": [ "fetch" ], "requestBody": { "required": true, "content": { "application/json": { "schema": { "type": "object", "required": [ "connector", "method", "path" ], "properties": { "connector": { "description": "Nom ou ID du connecteur", "examples": [ "github", "mailjet", "o2switch", "linkedin" ], "type": "string" }, "instance": { "description": "Nom ou ID de l'instance (pour multi-comptes)", "examples": [ "Jellyfin Famille", "GitHub Pro" ], "type": "string" }, "method": { "description": "Méthode HTTP", "examples": [ "GET", "POST", "PUT", "DELETE", "PATCH" ], "type": "string" }, "path": { "description": "Chemin de l'API (sera ajouté à base_url du connecteur)", "examples": [ "/user/repos", "/send", "/v2/userinfo" ], "type": "string" }, "headers": { "description": "Headers additionnels", "examples": [ { "X-Custom-Header": "value" } ], "type": "object", "patternProperties": { "^(.*)$": { "type": "string" } } }, "body": { "description": "Corps de la requête (pour POST/PUT/PATCH)", "examples": [ { "key": "value" } ] }, "query": { "description": "Query parameters", "examples": [ { "per_page": "10", "page": "1" } ], "type": "object", "patternProperties": { "^(.*)$": { "type": "string" } } } } } }, "multipart/form-data": { "schema": { "type": "object", "required": [ "connector", "method", "path" ], "properties": { "connector": { "description": "Nom ou ID du connecteur", "examples": [ "github", "mailjet", "o2switch", "linkedin" ], "type": "string" }, "instance": { "description": "Nom ou ID de l'instance (pour multi-comptes)", "examples": [ "Jellyfin Famille", "GitHub Pro" ], "type": "string" }, "method": { "description": "Méthode HTTP", "examples": [ "GET", "POST", "PUT", "DELETE", "PATCH" ], "type": "string" }, "path": { "description": "Chemin de l'API (sera ajouté à base_url du connecteur)", "examples": [ "/user/repos", "/send", "/v2/userinfo" ], "type": "string" }, "headers": { "description": "Headers additionnels", "examples": [ { "X-Custom-Header": "value" } ], "type": "object", "patternProperties": { "^(.*)$": { "type": "string" } } }, "body": { "description": "Corps de la requête (pour POST/PUT/PATCH)", "examples": [ { "key": "value" } ] }, "query": { "description": "Query parameters", "examples": [ { "per_page": "10", "page": "1" } ], "type": "object", "patternProperties": { "^(.*)$": { "type": "string" } } } } } }, "text/plain": { "schema": { "type": "object", "required": [ "connector", "method", "path" ], "properties": { "connector": { "description": "Nom ou ID du connecteur", "examples": [ "github", "mailjet", "o2switch", "linkedin" ], "type": "string" }, "instance": { "description": "Nom ou ID de l'instance (pour multi-comptes)", "examples": [ "Jellyfin Famille", "GitHub Pro" ], "type": "string" }, "method": { "description": "Méthode HTTP", "examples": [ "GET", "POST", "PUT", "DELETE", "PATCH" ], "type": "string" }, "path": { "description": "Chemin de l'API (sera ajouté à base_url du connecteur)", "examples": [ "/user/repos", "/send", "/v2/userinfo" ], "type": "string" }, "headers": { "description": "Headers additionnels", "examples": [ { "X-Custom-Header": "value" } ], "type": "object", "patternProperties": { "^(.*)$": { "type": "string" } } }, "body": { "description": "Corps de la requête (pour POST/PUT/PATCH)", "examples": [ { "key": "value" } ] }, "query": { "description": "Query parameters", "examples": [ { "per_page": "10", "page": "1" } ], "type": "object", "patternProperties": { "^(.*)$": { "type": "string" } } } } } } } } } }, "/api/auth/register": { "post": { "parameters": [], "responses": { "200": { "content": { "application/json": { "schema": { "type": "object", "properties": { "success": { "type": "boolean" }, "user": { "type": "object", "required": [ "id", "email", "created_at" ], "properties": { "id": { "type": "string" }, "email": { "type": "string" }, "created_at": { "type": "string" } } }, "session": { "type": "object", "required": [ "access_token", "refresh_token", "expires_in", "token_type" ], "properties": { "access_token": { "type": "string" }, "refresh_token": { "type": "string" }, "expires_in": { "type": "number" }, "token_type": { "type": "string" } } }, "error": { "type": "string" } }, "required": [ "success" ] } }, "multipart/form-data": { "schema": { "type": "object", "properties": { "success": { "type": "boolean" }, "user": { "type": "object", "required": [ "id", "email", "created_at" ], "properties": { "id": { "type": "string" }, "email": { "type": "string" }, "created_at": { "type": "string" } } }, "session": { "type": "object", "required": [ "access_token", "refresh_token", "expires_in", "token_type" ], "properties": { "access_token": { "type": "string" }, "refresh_token": { "type": "string" }, "expires_in": { "type": "number" }, "token_type": { "type": "string" } } }, "error": { "type": "string" } }, "required": [ "success" ] } }, "text/plain": { "schema": { "type": "object", "properties": { "success": { "type": "boolean" }, "user": { "type": "object", "required": [ "id", "email", "created_at" ], "properties": { "id": { "type": "string" }, "email": { "type": "string" }, "created_at": { "type": "string" } } }, "session": { "type": "object", "required": [ "access_token", "refresh_token", "expires_in", "token_type" ], "properties": { "access_token": { "type": "string" }, "refresh_token": { "type": "string" }, "expires_in": { "type": "number" }, "token_type": { "type": "string" } } }, "error": { "type": "string" } }, "required": [ "success" ] } } } } }, "operationId": "postApiAuthRegister", "summary": "Inscription", "description": "Créer un nouveau compte utilisateur", "tags": [ "auth" ], "requestBody": { "required": true, "content": { "application/json": { "schema": { "type": "object", "required": [ "email", "password" ], "properties": { "email": { "format": "email", "description": "Adresse email", "type": "string" }, "password": { "minLength": 6, "description": "Mot de passe (min 6 caractères)", "type": "string" } } } }, "multipart/form-data": { "schema": { "type": "object", "required": [ "email", "password" ], "properties": { "email": { "format": "email", "description": "Adresse email", "type": "string" }, "password": { "minLength": 6, "description": "Mot de passe (min 6 caractères)", "type": "string" } } } }, "text/plain": { "schema": { "type": "object", "required": [ "email", "password" ], "properties": { "email": { "format": "email", "description": "Adresse email", "type": "string" }, "password": { "minLength": 6, "description": "Mot de passe (min 6 caractères)", "type": "string" } } } } } } } }, "/api/auth/login": { "post": { "parameters": [], "responses": { "200": { "content": { "application/json": { "schema": { "type": "object", "properties": { "success": { "type": "boolean" }, "user": { "type": "object", "required": [ "id", "email", "created_at" ], "properties": { "id": { "description": "UUID de l'utilisateur", "type": "string" }, "email": { "type": "string" }, "created_at": { "type": "string" } } }, "session": { "type": "object", "required": [ "access_token", "refresh_token", "expires_in", "token_type" ], "properties": { "access_token": { "description": "JWT à utiliser dans Authorization header", "type": "string" }, "refresh_token": { "description": "Token pour rafraîchir la session", "type": "string" }, "expires_in": { "description": "Durée de validité en secondes", "type": "number" }, "token_type": { "type": "string" } } }, "error": { "type": "string" } }, "required": [ "success" ] } }, "multipart/form-data": { "schema": { "type": "object", "properties": { "success": { "type": "boolean" }, "user": { "type": "object", "required": [ "id", "email", "created_at" ], "properties": { "id": { "description": "UUID de l'utilisateur", "type": "string" }, "email": { "type": "string" }, "created_at": { "type": "string" } } }, "session": { "type": "object", "required": [ "access_token", "refresh_token", "expires_in", "token_type" ], "properties": { "access_token": { "description": "JWT à utiliser dans Authorization header", "type": "string" }, "refresh_token": { "description": "Token pour rafraîchir la session", "type": "string" }, "expires_in": { "description": "Durée de validité en secondes", "type": "number" }, "token_type": { "type": "string" } } }, "error": { "type": "string" } }, "required": [ "success" ] } }, "text/plain": { "schema": { "type": "object", "properties": { "success": { "type": "boolean" }, "user": { "type": "object", "required": [ "id", "email", "created_at" ], "properties": { "id": { "description": "UUID de l'utilisateur", "type": "string" }, "email": { "type": "string" }, "created_at": { "type": "string" } } }, "session": { "type": "object", "required": [ "access_token", "refresh_token", "expires_in", "token_type" ], "properties": { "access_token": { "description": "JWT à utiliser dans Authorization header", "type": "string" }, "refresh_token": { "description": "Token pour rafraîchir la session", "type": "string" }, "expires_in": { "description": "Durée de validité en secondes", "type": "number" }, "token_type": { "type": "string" } } }, "error": { "type": "string" } }, "required": [ "success" ] } } } } }, "operationId": "postApiAuthLogin", "summary": "Connexion", "description": "Connecter un utilisateur et obtenir un JWT", "tags": [ "auth" ], "requestBody": { "required": true, "content": { "application/json": { "schema": { "type": "object", "required": [ "email", "password" ], "properties": { "email": { "format": "email", "type": "string" }, "password": { "type": "string" } } } }, "multipart/form-data": { "schema": { "type": "object", "required": [ "email", "password" ], "properties": { "email": { "format": "email", "type": "string" }, "password": { "type": "string" } } } }, "text/plain": { "schema": { "type": "object", "required": [ "email", "password" ], "properties": { "email": { "format": "email", "type": "string" }, "password": { "type": "string" } } } } } } } }, "/api/auth/logout": { "post": { "responses": { "200": { "content": { "application/json": { "schema": { "type": "object", "properties": { "success": { "type": "boolean" }, "error": { "type": "string" } }, "required": [ "success" ] } }, "multipart/form-data": { "schema": { "type": "object", "properties": { "success": { "type": "boolean" }, "error": { "type": "string" } }, "required": [ "success" ] } }, "text/plain": { "schema": { "type": "object", "properties": { "success": { "type": "boolean" }, "error": { "type": "string" } }, "required": [ "success" ] } } } } }, "operationId": "postApiAuthLogout", "summary": "Déconnexion", "description": "Invalider la session", "security": [ { "bearerAuth": [] } ], "tags": [ "auth" ] } }, "/api/auth/me": { "get": { "responses": { "200": { "content": { "application/json": { "schema": { "type": "object", "properties": { "success": { "type": "boolean" }, "user": { "type": "object", "required": [ "id", "email", "created_at" ], "properties": { "id": { "type": "string" }, "email": { "type": "string" }, "created_at": { "type": "string" } } }, "error": { "type": "string" } }, "required": [ "success" ] } }, "multipart/form-data": { "schema": { "type": "object", "properties": { "success": { "type": "boolean" }, "user": { "type": "object", "required": [ "id", "email", "created_at" ], "properties": { "id": { "type": "string" }, "email": { "type": "string" }, "created_at": { "type": "string" } } }, "error": { "type": "string" } }, "required": [ "success" ] } }, "text/plain": { "schema": { "type": "object", "properties": { "success": { "type": "boolean" }, "user": { "type": "object", "required": [ "id", "email", "created_at" ], "properties": { "id": { "type": "string" }, "email": { "type": "string" }, "created_at": { "type": "string" } } }, "error": { "type": "string" } }, "required": [ "success" ] } } } } }, "operationId": "getApiAuthMe", "summary": "Profil utilisateur", "description": "Récupérer les infos du user connecté", "security": [ { "bearerAuth": [] } ], "tags": [ "auth" ] }, "put": { "parameters": [], "responses": { "200": { "content": { "application/json": { "schema": { "type": "object", "properties": { "success": { "type": "boolean" }, "user": { "type": "object", "required": [ "id", "email", "created_at" ], "properties": { "id": { "type": "string" }, "email": { "type": "string" }, "created_at": { "type": "string" } } }, "error": { "type": "string" } }, "required": [ "success" ] } }, "multipart/form-data": { "schema": { "type": "object", "properties": { "success": { "type": "boolean" }, "user": { "type": "object", "required": [ "id", "email", "created_at" ], "properties": { "id": { "type": "string" }, "email": { "type": "string" }, "created_at": { "type": "string" } } }, "error": { "type": "string" } }, "required": [ "success" ] } }, "text/plain": { "schema": { "type": "object", "properties": { "success": { "type": "boolean" }, "user": { "type": "object", "required": [ "id", "email", "created_at" ], "properties": { "id": { "type": "string" }, "email": { "type": "string" }, "created_at": { "type": "string" } } }, "error": { "type": "string" } }, "required": [ "success" ] } } } } }, "operationId": "putApiAuthMe", "summary": "Modifier profil", "description": "Modifier l'email ou les métadonnées de l'utilisateur connecté", "security": [ { "bearerAuth": [] } ], "tags": [ "auth" ], "requestBody": { "required": true, "content": { "application/json": { "schema": { "type": "object", "properties": { "email": { "format": "email", "description": "Nouvel email", "type": "string" }, "metadata": { "description": "Métadonnées custom", "type": "object", "patternProperties": { "^(.*)$": {} } } } } }, "multipart/form-data": { "schema": { "type": "object", "properties": { "email": { "format": "email", "description": "Nouvel email", "type": "string" }, "metadata": { "description": "Métadonnées custom", "type": "object", "patternProperties": { "^(.*)$": {} } } } } }, "text/plain": { "schema": { "type": "object", "properties": { "email": { "format": "email", "description": "Nouvel email", "type": "string" }, "metadata": { "description": "Métadonnées custom", "type": "object", "patternProperties": { "^(.*)$": {} } } } } } } } } }, "/api/auth/refresh": { "post": { "parameters": [], "responses": { "200": { "content": { "application/json": { "schema": { "type": "object", "properties": { "success": { "type": "boolean" }, "session": { "type": "object", "required": [ "access_token", "refresh_token", "expires_in", "token_type" ], "properties": { "access_token": { "type": "string" }, "refresh_token": { "type": "string" }, "expires_in": { "type": "number" }, "token_type": { "type": "string" } } }, "error": { "type": "string" } }, "required": [ "success" ] } }, "multipart/form-data": { "schema": { "type": "object", "properties": { "success": { "type": "boolean" }, "session": { "type": "object", "required": [ "access_token", "refresh_token", "expires_in", "token_type" ], "properties": { "access_token": { "type": "string" }, "refresh_token": { "type": "string" }, "expires_in": { "type": "number" }, "token_type": { "type": "string" } } }, "error": { "type": "string" } }, "required": [ "success" ] } }, "text/plain": { "schema": { "type": "object", "properties": { "success": { "type": "boolean" }, "session": { "type": "object", "required": [ "access_token", "refresh_token", "expires_in", "token_type" ], "properties": { "access_token": { "type": "string" }, "refresh_token": { "type": "string" }, "expires_in": { "type": "number" }, "token_type": { "type": "string" } } }, "error": { "type": "string" } }, "required": [ "success" ] } } } } }, "operationId": "postApiAuthRefresh", "summary": "Rafraîchir session", "description": "Obtenir un nouveau access_token", "tags": [ "auth" ], "requestBody": { "required": true, "content": { "application/json": { "schema": { "type": "object", "required": [ "refresh_token" ], "properties": { "refresh_token": { "description": "Refresh token obtenu lors du login", "type": "string" } } } }, "multipart/form-data": { "schema": { "type": "object", "required": [ "refresh_token" ], "properties": { "refresh_token": { "description": "Refresh token obtenu lors du login", "type": "string" } } } }, "text/plain": { "schema": { "type": "object", "required": [ "refresh_token" ], "properties": { "refresh_token": { "description": "Refresh token obtenu lors du login", "type": "string" } } } } } } } }, "/api/auth/forgot-password": { "post": { "parameters": [], "responses": { "200": { "content": { "application/json": { "schema": { "type": "object", "properties": { "success": { "type": "boolean" }, "error": { "type": "string" } }, "required": [ "success" ] } }, "multipart/form-data": { "schema": { "type": "object", "properties": { "success": { "type": "boolean" }, "error": { "type": "string" } }, "required": [ "success" ] } }, "text/plain": { "schema": { "type": "object", "properties": { "success": { "type": "boolean" }, "error": { "type": "string" } }, "required": [ "success" ] } } } } }, "operationId": "postApiAuthForgot-password", "summary": "Mot de passe oublié", "description": "Envoie un email avec un lien de réinitialisation. Retourne toujours success=true pour ne pas révéler si l'email existe.", "tags": [ "auth" ], "requestBody": { "required": true, "content": { "application/json": { "schema": { "type": "object", "required": [ "email" ], "properties": { "email": { "format": "email", "description": "Adresse email du compte", "type": "string" } } } }, "multipart/form-data": { "schema": { "type": "object", "required": [ "email" ], "properties": { "email": { "format": "email", "description": "Adresse email du compte", "type": "string" } } } }, "text/plain": { "schema": { "type": "object", "required": [ "email" ], "properties": { "email": { "format": "email", "description": "Adresse email du compte", "type": "string" } } } } } } } }, "/api/auth/change-password": { "post": { "parameters": [], "responses": { "200": { "content": { "application/json": { "schema": { "type": "object", "properties": { "success": { "type": "boolean" }, "error": { "type": "string" } }, "required": [ "success" ] } }, "multipart/form-data": { "schema": { "type": "object", "properties": { "success": { "type": "boolean" }, "error": { "type": "string" } }, "required": [ "success" ] } }, "text/plain": { "schema": { "type": "object", "properties": { "success": { "type": "boolean" }, "error": { "type": "string" } }, "required": [ "success" ] } } } } }, "operationId": "postApiAuthChange-password", "summary": "Changer mot de passe", "description": "Change le mot de passe de l'utilisateur connecté", "security": [ { "bearerAuth": [] } ], "tags": [ "auth" ], "requestBody": { "required": true, "content": { "application/json": { "schema": { "type": "object", "required": [ "new_password" ], "properties": { "new_password": { "minLength": 6, "description": "Nouveau mot de passe (min 6 caractères)", "type": "string" } } } }, "multipart/form-data": { "schema": { "type": "object", "required": [ "new_password" ], "properties": { "new_password": { "minLength": 6, "description": "Nouveau mot de passe (min 6 caractères)", "type": "string" } } } }, "text/plain": { "schema": { "type": "object", "required": [ "new_password" ], "properties": { "new_password": { "minLength": 6, "description": "Nouveau mot de passe (min 6 caractères)", "type": "string" } } } } } } } }, "/api/auth/disable-account": { "post": { "responses": { "200": { "content": { "application/json": { "schema": { "type": "object", "properties": { "success": { "type": "boolean" }, "error": { "type": "string" } }, "required": [ "success" ] } }, "multipart/form-data": { "schema": { "type": "object", "properties": { "success": { "type": "boolean" }, "error": { "type": "string" } }, "required": [ "success" ] } }, "text/plain": { "schema": { "type": "object", "properties": { "success": { "type": "boolean" }, "error": { "type": "string" } }, "required": [ "success" ] } } } } }, "operationId": "postApiAuthDisable-account", "summary": "Désactiver compte", "description": "Désactive le compte et révoque la session. Le compte est conservé 30 jours avant suppression définitive.", "security": [ { "bearerAuth": [] } ], "tags": [ "auth" ] } }, "/api/auth/api-keys": { "post": { "parameters": [], "responses": { "200": { "content": { "application/json": { "schema": { "type": "object", "properties": { "success": { "type": "boolean" }, "key": { "description": "Clé API complète (affichée uniquement ici!)", "type": "string" }, "api_key": { "type": "object", "required": [ "id", "name", "key_prefix", "scopes", "expires_at", "created_at" ], "properties": { "id": { "type": "string" }, "name": { "type": "string" }, "key_prefix": { "description": "Préfixe pour identification (ex: ck_live_abc1)", "type": "string" }, "scopes": { "type": "array", "items": { "type": "string" } }, "expires_at": { "anyOf": [ { "type": "string" }, { "type": "null" } ] }, "created_at": { "type": "string" } } }, "error": { "type": "string" } }, "required": [ "success" ] } }, "multipart/form-data": { "schema": { "type": "object", "properties": { "success": { "type": "boolean" }, "key": { "description": "Clé API complète (affichée uniquement ici!)", "type": "string" }, "api_key": { "type": "object", "required": [ "id", "name", "key_prefix", "scopes", "expires_at", "created_at" ], "properties": { "id": { "type": "string" }, "name": { "type": "string" }, "key_prefix": { "description": "Préfixe pour identification (ex: ck_live_abc1)", "type": "string" }, "scopes": { "type": "array", "items": { "type": "string" } }, "expires_at": { "anyOf": [ { "type": "string" }, { "type": "null" } ] }, "created_at": { "type": "string" } } }, "error": { "type": "string" } }, "required": [ "success" ] } }, "text/plain": { "schema": { "type": "object", "properties": { "success": { "type": "boolean" }, "key": { "description": "Clé API complète (affichée uniquement ici!)", "type": "string" }, "api_key": { "type": "object", "required": [ "id", "name", "key_prefix", "scopes", "expires_at", "created_at" ], "properties": { "id": { "type": "string" }, "name": { "type": "string" }, "key_prefix": { "description": "Préfixe pour identification (ex: ck_live_abc1)", "type": "string" }, "scopes": { "type": "array", "items": { "type": "string" } }, "expires_at": { "anyOf": [ { "type": "string" }, { "type": "null" } ] }, "created_at": { "type": "string" } } }, "error": { "type": "string" } }, "required": [ "success" ] } } } } }, "operationId": "postApiAuthApi-keys", "summary": "Créer une clé API", "description": "Crée une clé API pour l'authentification programmatique.\n\n**IMPORTANT:** La clé complète n'est affichée qu'une seule fois à la création. Conservez-la précieusement!\n\n**Scopes disponibles:**\n- `*` : Accès complet\n- `fetch` : Appeler /api/fetch\n- `connectors:read` : Lire les connecteurs\n- `connectors:write` : Créer/modifier des connecteurs\n- `instances:read` : Lire ses instances\n- `instances:write` : Créer/modifier ses instances\n- `audit:read` : Voir les logs d'audit\n\n**Usage:**\n```bash\ncurl -H \"X-API-Key: ck_live_xxx...\" https://connectors.33800.nowhere84.com/api/fetch\n```", "security": [ { "bearerAuth": [] } ], "tags": [ "auth" ], "requestBody": { "required": true, "content": { "application/json": { "schema": { "type": "object", "required": [ "name" ], "properties": { "name": { "description": "Nom de la clé (ex: \"Script backup\", \"CI/CD\")", "examples": [ "Mon script" ], "type": "string" }, "scopes": { "description": "Permissions (défaut: fetch, connectors:read, instances:*, audit:read)", "examples": [ [ "fetch", "connectors:read" ] ], "type": "array", "items": { "type": "string" } }, "expires_in_days": { "description": "Expiration en jours (null = jamais)", "examples": [ 30, 90, 365 ], "type": "number" } } } }, "multipart/form-data": { "schema": { "type": "object", "required": [ "name" ], "properties": { "name": { "description": "Nom de la clé (ex: \"Script backup\", \"CI/CD\")", "examples": [ "Mon script" ], "type": "string" }, "scopes": { "description": "Permissions (défaut: fetch, connectors:read, instances:*, audit:read)", "examples": [ [ "fetch", "connectors:read" ] ], "type": "array", "items": { "type": "string" } }, "expires_in_days": { "description": "Expiration en jours (null = jamais)", "examples": [ 30, 90, 365 ], "type": "number" } } } }, "text/plain": { "schema": { "type": "object", "required": [ "name" ], "properties": { "name": { "description": "Nom de la clé (ex: \"Script backup\", \"CI/CD\")", "examples": [ "Mon script" ], "type": "string" }, "scopes": { "description": "Permissions (défaut: fetch, connectors:read, instances:*, audit:read)", "examples": [ [ "fetch", "connectors:read" ] ], "type": "array", "items": { "type": "string" } }, "expires_in_days": { "description": "Expiration en jours (null = jamais)", "examples": [ 30, 90, 365 ], "type": "number" } } } } } } }, "get": { "responses": { "200": { "content": { "application/json": { "schema": { "type": "object", "properties": { "success": { "type": "boolean" }, "api_keys": { "type": "array", "items": { "type": "object", "required": [ "id", "name", "key_prefix", "scopes", "expires_at", "last_used_at", "created_at", "is_revoked" ], "properties": { "id": { "type": "string" }, "name": { "type": "string" }, "key_prefix": { "type": "string" }, "scopes": { "type": "array", "items": { "type": "string" } }, "expires_at": { "anyOf": [ { "type": "string" }, { "type": "null" } ] }, "last_used_at": { "anyOf": [ { "type": "string" }, { "type": "null" } ] }, "created_at": { "type": "string" }, "is_revoked": { "type": "boolean" } } } }, "error": { "type": "string" } }, "required": [ "success" ] } }, "multipart/form-data": { "schema": { "type": "object", "properties": { "success": { "type": "boolean" }, "api_keys": { "type": "array", "items": { "type": "object", "required": [ "id", "name", "key_prefix", "scopes", "expires_at", "last_used_at", "created_at", "is_revoked" ], "properties": { "id": { "type": "string" }, "name": { "type": "string" }, "key_prefix": { "type": "string" }, "scopes": { "type": "array", "items": { "type": "string" } }, "expires_at": { "anyOf": [ { "type": "string" }, { "type": "null" } ] }, "last_used_at": { "anyOf": [ { "type": "string" }, { "type": "null" } ] }, "created_at": { "type": "string" }, "is_revoked": { "type": "boolean" } } } }, "error": { "type": "string" } }, "required": [ "success" ] } }, "text/plain": { "schema": { "type": "object", "properties": { "success": { "type": "boolean" }, "api_keys": { "type": "array", "items": { "type": "object", "required": [ "id", "name", "key_prefix", "scopes", "expires_at", "last_used_at", "created_at", "is_revoked" ], "properties": { "id": { "type": "string" }, "name": { "type": "string" }, "key_prefix": { "type": "string" }, "scopes": { "type": "array", "items": { "type": "string" } }, "expires_at": { "anyOf": [ { "type": "string" }, { "type": "null" } ] }, "last_used_at": { "anyOf": [ { "type": "string" }, { "type": "null" } ] }, "created_at": { "type": "string" }, "is_revoked": { "type": "boolean" } } } }, "error": { "type": "string" } }, "required": [ "success" ] } } } } }, "operationId": "getApiAuthApi-keys", "summary": "Lister mes clés API", "description": "Liste toutes les clés API de l'utilisateur (sans les valeurs)", "security": [ { "bearerAuth": [] } ], "tags": [ "auth" ] } }, "/api/auth/api-keys/{id}": { "delete": { "parameters": [ { "description": "ID de la clé API", "schema": { "type": "string" }, "in": "path", "name": "id", "required": true } ], "responses": { "200": { "content": { "application/json": { "schema": { "type": "object", "properties": { "success": { "type": "boolean" }, "error": { "type": "string" } }, "required": [ "success" ] } }, "multipart/form-data": { "schema": { "type": "object", "properties": { "success": { "type": "boolean" }, "error": { "type": "string" } }, "required": [ "success" ] } }, "text/plain": { "schema": { "type": "object", "properties": { "success": { "type": "boolean" }, "error": { "type": "string" } }, "required": [ "success" ] } } } } }, "operationId": "deleteApiAuthApi-keysById", "summary": "Révoquer une clé API", "description": "Révoque une clé API. Cette action est irréversible.", "security": [ { "bearerAuth": [] } ], "tags": [ "auth" ] } }, "/api/connector-types": { "get": { "responses": { "200": { "content": { "application/json": { "schema": { "type": "object", "properties": { "types": { "type": "array", "items": { "type": "object", "required": [ "id", "name", "display_name", "description", "api_version", "auth_type", "endpoints_count" ], "properties": { "id": { "type": "string" }, "name": { "type": "string" }, "display_name": { "type": "string" }, "description": { "type": "string" }, "api_version": { "type": "string" }, "docs_url": { "type": "string" }, "auth_type": { "type": "string" }, "endpoints_count": { "type": "number" } } } } }, "required": [ "types" ] } }, "multipart/form-data": { "schema": { "type": "object", "properties": { "types": { "type": "array", "items": { "type": "object", "required": [ "id", "name", "display_name", "description", "api_version", "auth_type", "endpoints_count" ], "properties": { "id": { "type": "string" }, "name": { "type": "string" }, "display_name": { "type": "string" }, "description": { "type": "string" }, "api_version": { "type": "string" }, "docs_url": { "type": "string" }, "auth_type": { "type": "string" }, "endpoints_count": { "type": "number" } } } } }, "required": [ "types" ] } }, "text/plain": { "schema": { "type": "object", "properties": { "types": { "type": "array", "items": { "type": "object", "required": [ "id", "name", "display_name", "description", "api_version", "auth_type", "endpoints_count" ], "properties": { "id": { "type": "string" }, "name": { "type": "string" }, "display_name": { "type": "string" }, "description": { "type": "string" }, "api_version": { "type": "string" }, "docs_url": { "type": "string" }, "auth_type": { "type": "string" }, "endpoints_count": { "type": "number" } } } } }, "required": [ "types" ] } } } } }, "operationId": "getApiConnector-types", "summary": "Lister les types de connecteurs", "description": "Liste tous les types de connecteurs prédéfinis disponibles (github, mailjet, linkedin, o2switch)", "tags": [ "connectors" ] } }, "/api/connector-types/{typeId}": { "get": { "parameters": [ { "schema": { "type": "string" }, "in": "path", "name": "typeId", "required": true } ], "responses": { "200": { "content": { "application/json": { "schema": { "type": "object", "properties": { "type": { "type": "object", "required": [ "id", "name", "display_name", "description", "base_url", "api_version", "auth_type", "endpoints" ], "properties": { "id": { "type": "string" }, "name": { "type": "string" }, "display_name": { "type": "string" }, "description": { "type": "string" }, "base_url": { "type": "string" }, "api_version": { "type": "string" }, "docs_url": { "type": "string" }, "auth_type": { "type": "string" }, "auth_config": {}, "endpoints": { "type": "array", "items": { "type": "object", "required": [ "method", "path", "entity", "action", "summary" ], "properties": { "method": { "type": "string" }, "path": { "type": "string" }, "entity": { "type": "string" }, "action": { "type": "string" }, "summary": { "type": "string" } } } } } }, "error": { "type": "string" } } } }, "multipart/form-data": { "schema": { "type": "object", "properties": { "type": { "type": "object", "required": [ "id", "name", "display_name", "description", "base_url", "api_version", "auth_type", "endpoints" ], "properties": { "id": { "type": "string" }, "name": { "type": "string" }, "display_name": { "type": "string" }, "description": { "type": "string" }, "base_url": { "type": "string" }, "api_version": { "type": "string" }, "docs_url": { "type": "string" }, "auth_type": { "type": "string" }, "auth_config": {}, "endpoints": { "type": "array", "items": { "type": "object", "required": [ "method", "path", "entity", "action", "summary" ], "properties": { "method": { "type": "string" }, "path": { "type": "string" }, "entity": { "type": "string" }, "action": { "type": "string" }, "summary": { "type": "string" } } } } } }, "error": { "type": "string" } } } }, "text/plain": { "schema": { "type": "object", "properties": { "type": { "type": "object", "required": [ "id", "name", "display_name", "description", "base_url", "api_version", "auth_type", "endpoints" ], "properties": { "id": { "type": "string" }, "name": { "type": "string" }, "display_name": { "type": "string" }, "description": { "type": "string" }, "base_url": { "type": "string" }, "api_version": { "type": "string" }, "docs_url": { "type": "string" }, "auth_type": { "type": "string" }, "auth_config": {}, "endpoints": { "type": "array", "items": { "type": "object", "required": [ "method", "path", "entity", "action", "summary" ], "properties": { "method": { "type": "string" }, "path": { "type": "string" }, "entity": { "type": "string" }, "action": { "type": "string" }, "summary": { "type": "string" } } } } } }, "error": { "type": "string" } } } } } } }, "operationId": "getApiConnector-typesByTypeId", "summary": "Détails d'un type de connecteur", "description": "Retourne le type avec tous ses endpoints prédéfinis", "tags": [ "connectors" ] } }, "/api/connectors/{id}/provision-type": { "post": { "parameters": [ { "schema": { "type": "string" }, "in": "path", "name": "id", "required": true } ], "responses": { "200": { "content": { "application/json": { "schema": { "type": "object", "properties": { "success": { "type": "boolean" }, "type_id": { "type": "string" }, "created": { "type": "number" }, "updated": { "type": "number" }, "total": { "type": "number" }, "error": { "type": "string" } } } }, "multipart/form-data": { "schema": { "type": "object", "properties": { "success": { "type": "boolean" }, "type_id": { "type": "string" }, "created": { "type": "number" }, "updated": { "type": "number" }, "total": { "type": "number" }, "error": { "type": "string" } } } }, "text/plain": { "schema": { "type": "object", "properties": { "success": { "type": "boolean" }, "type_id": { "type": "string" }, "created": { "type": "number" }, "updated": { "type": "number" }, "total": { "type": "number" }, "error": { "type": "string" } } } } } } }, "operationId": "postApiConnectorsByIdProvision-type", "summary": "Provisionner les endpoints d'un type", "description": "Copie tous les endpoints prédéfinis d'un type vers ce connecteur", "tags": [ "connectors" ], "requestBody": { "required": true, "content": { "application/json": { "schema": { "type": "object", "required": [ "type_id" ], "properties": { "type_id": { "description": "ID du type (github, mailjet, linkedin, o2switch)", "type": "string" } } } }, "multipart/form-data": { "schema": { "type": "object", "required": [ "type_id" ], "properties": { "type_id": { "description": "ID du type (github, mailjet, linkedin, o2switch)", "type": "string" } } } }, "text/plain": { "schema": { "type": "object", "required": [ "type_id" ], "properties": { "type_id": { "description": "ID du type (github, mailjet, linkedin, o2switch)", "type": "string" } } } } } } } }, "/api/connectors": { "get": { "responses": { "200": { "content": { "application/json": { "schema": { "type": "object", "properties": { "connectors": { "type": "array", "items": { "type": "object", "required": [ "id", "name", "display_name", "auth_type", "is_connected", "is_public", "expires_at", "description" ], "properties": { "id": { "type": "string" }, "name": { "type": "string" }, "display_name": { "type": "string" }, "auth_type": { "type": "string" }, "is_connected": { "type": "boolean" }, "is_public": { "type": "boolean" }, "expires_at": { "anyOf": [ { "type": "string" }, { "type": "null" } ] }, "description": { "anyOf": [ { "type": "string" }, { "type": "null" } ] } } } }, "error": { "type": "string" } } } }, "multipart/form-data": { "schema": { "type": "object", "properties": { "connectors": { "type": "array", "items": { "type": "object", "required": [ "id", "name", "display_name", "auth_type", "is_connected", "is_public", "expires_at", "description" ], "properties": { "id": { "type": "string" }, "name": { "type": "string" }, "display_name": { "type": "string" }, "auth_type": { "type": "string" }, "is_connected": { "type": "boolean" }, "is_public": { "type": "boolean" }, "expires_at": { "anyOf": [ { "type": "string" }, { "type": "null" } ] }, "description": { "anyOf": [ { "type": "string" }, { "type": "null" } ] } } } }, "error": { "type": "string" } } } }, "text/plain": { "schema": { "type": "object", "properties": { "connectors": { "type": "array", "items": { "type": "object", "required": [ "id", "name", "display_name", "auth_type", "is_connected", "is_public", "expires_at", "description" ], "properties": { "id": { "type": "string" }, "name": { "type": "string" }, "display_name": { "type": "string" }, "auth_type": { "type": "string" }, "is_connected": { "type": "boolean" }, "is_public": { "type": "boolean" }, "expires_at": { "anyOf": [ { "type": "string" }, { "type": "null" } ] }, "description": { "anyOf": [ { "type": "string" }, { "type": "null" } ] } } } }, "error": { "type": "string" } } } } } } }, "operationId": "getApiConnectors", "summary": "Lister les connecteurs", "description": "Liste tous les connecteurs disponibles avec leur statut de connexion", "security": [ { "bearerAuth": [] } ], "tags": [ "connectors" ] }, "post": { "parameters": [], "operationId": "postApiConnectors", "summary": "Créer un connecteur", "description": "Crée un nouveau connecteur et déclenche automatiquement la découverte du schema.\n\n**Auto-discovery:**\n1. Si swagger_url fourni → importe le swagger\n2. Sinon → cherche le swagger aux URLs communes\n3. Sinon → explore les endpoints courants\n\nLa découverte s'exécute en arrière-plan. Utilisez GET /api/connectors/:id/schema pour voir les résultats.", "tags": [ "connectors" ], "requestBody": { "required": true, "content": { "application/json": { "schema": { "type": "object", "required": [ "name", "base_url", "auth_type" ], "properties": { "name": { "description": "Identifiant unique (slug)", "examples": [ "my-api" ], "type": "string" }, "display_name": { "description": "Nom d'affichage", "examples": [ "My API" ], "type": "string" }, "base_url": { "description": "URL de base de l'API", "examples": [ "https://api.example.com" ], "type": "string" }, "auth_type": { "description": "Type d'authentification", "examples": [ "bearer", "basic", "api_key", "oauth2", "custom" ], "type": "string" }, "auth_config": { "description": "Configuration spécifique au type d'auth" }, "swagger_url": { "description": "URL du swagger/OpenAPI (optionnel, sera auto-détecté sinon)", "type": "string" }, "description": { "type": "string" }, "auto_discover": { "description": "Lancer auto-discovery (default: true)", "default": true, "type": "boolean" } } } }, "multipart/form-data": { "schema": { "type": "object", "required": [ "name", "base_url", "auth_type" ], "properties": { "name": { "description": "Identifiant unique (slug)", "examples": [ "my-api" ], "type": "string" }, "display_name": { "description": "Nom d'affichage", "examples": [ "My API" ], "type": "string" }, "base_url": { "description": "URL de base de l'API", "examples": [ "https://api.example.com" ], "type": "string" }, "auth_type": { "description": "Type d'authentification", "examples": [ "bearer", "basic", "api_key", "oauth2", "custom" ], "type": "string" }, "auth_config": { "description": "Configuration spécifique au type d'auth" }, "swagger_url": { "description": "URL du swagger/OpenAPI (optionnel, sera auto-détecté sinon)", "type": "string" }, "description": { "type": "string" }, "auto_discover": { "description": "Lancer auto-discovery (default: true)", "default": true, "type": "boolean" } } } }, "text/plain": { "schema": { "type": "object", "required": [ "name", "base_url", "auth_type" ], "properties": { "name": { "description": "Identifiant unique (slug)", "examples": [ "my-api" ], "type": "string" }, "display_name": { "description": "Nom d'affichage", "examples": [ "My API" ], "type": "string" }, "base_url": { "description": "URL de base de l'API", "examples": [ "https://api.example.com" ], "type": "string" }, "auth_type": { "description": "Type d'authentification", "examples": [ "bearer", "basic", "api_key", "oauth2", "custom" ], "type": "string" }, "auth_config": { "description": "Configuration spécifique au type d'auth" }, "swagger_url": { "description": "URL du swagger/OpenAPI (optionnel, sera auto-détecté sinon)", "type": "string" }, "description": { "type": "string" }, "auto_discover": { "description": "Lancer auto-discovery (default: true)", "default": true, "type": "boolean" } } } } } }, "responses": { "200": {} } } }, "/api/connectors/{id}": { "get": { "parameters": [ { "description": "Nom ou UUID du connecteur", "schema": { "type": "string" }, "in": "path", "name": "id", "required": true } ], "operationId": "getApiConnectorsById", "summary": "Détails d'un connecteur", "security": [ { "bearerAuth": [] } ], "tags": [ "connectors" ], "responses": { "200": {} } }, "delete": { "parameters": [ { "schema": { "type": "string" }, "in": "path", "name": "id", "required": true } ], "operationId": "deleteApiConnectorsById", "summary": "Supprimer un connecteur", "tags": [ "connectors" ], "responses": { "200": {} } } }, "/api/connectors/{id}/rediscover": { "post": { "parameters": [ { "schema": { "type": "string" }, "in": "path", "name": "id", "required": true } ], "responses": { "200": { "content": { "application/json": { "schema": { "type": "object", "properties": { "success": { "type": "boolean" }, "status": { "type": "string" }, "source": { "type": "string" }, "swagger_url": { "type": "string" }, "count": { "type": "number" }, "discovered": { "type": "array", "items": { "type": "string" } }, "message": { "type": "string" }, "error": { "type": "string" } } } }, "multipart/form-data": { "schema": { "type": "object", "properties": { "success": { "type": "boolean" }, "status": { "type": "string" }, "source": { "type": "string" }, "swagger_url": { "type": "string" }, "count": { "type": "number" }, "discovered": { "type": "array", "items": { "type": "string" } }, "message": { "type": "string" }, "error": { "type": "string" } } } }, "text/plain": { "schema": { "type": "object", "properties": { "success": { "type": "boolean" }, "status": { "type": "string" }, "source": { "type": "string" }, "swagger_url": { "type": "string" }, "count": { "type": "number" }, "discovered": { "type": "array", "items": { "type": "string" } }, "message": { "type": "string" }, "error": { "type": "string" } } } } } } }, "operationId": "postApiConnectorsByIdRediscover", "summary": "Relancer la découverte", "description": "Relance la découverte du schema API pour ce connecteur.\n\nUtile pour:\n- Mettre à jour après changement d'API\n- Réessayer après un échec\n- Forcer un nouveau swagger_url", "security": [ { "bearerAuth": [] } ], "tags": [ "connectors" ], "requestBody": { "required": true, "content": { "application/json": { "schema": { "type": "object", "properties": { "swagger_url": { "description": "Nouvelle URL swagger (optionnel)", "type": "string" } } } }, "multipart/form-data": { "schema": { "type": "object", "properties": { "swagger_url": { "description": "Nouvelle URL swagger (optionnel)", "type": "string" } } } }, "text/plain": { "schema": { "type": "object", "properties": { "swagger_url": { "description": "Nouvelle URL swagger (optionnel)", "type": "string" } } } } } } } }, "/api/connectors/{id}/schema": { "get": { "parameters": [ { "schema": { "type": "string" }, "in": "path", "name": "id", "required": true } ], "responses": { "200": { "content": { "application/json": { "schema": { "type": "object", "properties": { "schema": { "type": "object", "required": [ "connector_id", "connector_name", "source", "updated_at", "endpoints", "entities" ], "properties": { "connector_id": { "type": "string" }, "connector_name": { "type": "string" }, "version": { "type": "string" }, "source": { "type": "string" }, "updated_at": { "type": "string" }, "endpoints": { "type": "array", "items": {} }, "entities": {} } }, "error": { "type": "string" } } } }, "multipart/form-data": { "schema": { "type": "object", "properties": { "schema": { "type": "object", "required": [ "connector_id", "connector_name", "source", "updated_at", "endpoints", "entities" ], "properties": { "connector_id": { "type": "string" }, "connector_name": { "type": "string" }, "version": { "type": "string" }, "source": { "type": "string" }, "updated_at": { "type": "string" }, "endpoints": { "type": "array", "items": {} }, "entities": {} } }, "error": { "type": "string" } } } }, "text/plain": { "schema": { "type": "object", "properties": { "schema": { "type": "object", "required": [ "connector_id", "connector_name", "source", "updated_at", "endpoints", "entities" ], "properties": { "connector_id": { "type": "string" }, "connector_name": { "type": "string" }, "version": { "type": "string" }, "source": { "type": "string" }, "updated_at": { "type": "string" }, "endpoints": { "type": "array", "items": {} }, "entities": {} } }, "error": { "type": "string" } } } } } } }, "operationId": "getApiConnectorsByIdSchema", "summary": "Schema complet du connecteur", "description": "Retourne le schema complet du connecteur avec tous les endpoints decouverts,\nles entites detectees et leurs champs.\n\nCe schema est utilise par QIG pour generer des interfaces dynamiques.", "tags": [ "connectors" ] } }, "/api/connectors/{id}/openapi": { "get": { "parameters": [ { "schema": { "type": "string" }, "in": "path", "name": "id", "required": true } ], "operationId": "getApiConnectorsByIdOpenapi", "summary": "OpenAPI spec générée", "description": "Génère une spec OpenAPI 3.0 à partir des endpoints connus.\n\nUtile pour:\n- Afficher un mini Swagger même si l'API n'en propose pas\n- Importer dans Postman ou autres outils\n- Documentation auto-générée", "tags": [ "connectors" ], "responses": { "200": {} } } }, "/api/connectors/{id}/endpoints": { "get": { "parameters": [ { "schema": { "type": "string" }, "in": "path", "name": "id", "required": true }, { "description": "Filtrer par entite (ex: project, user)", "schema": { "type": "string" }, "in": "query", "name": "entity", "required": false }, { "description": "Filtrer par action (list, get, create, update, delete)", "schema": { "type": "string" }, "in": "query", "name": "action", "required": false } ], "responses": { "200": { "content": { "application/json": { "schema": { "type": "object", "properties": { "endpoints": { "type": "array", "items": { "type": "object", "required": [ "id", "path", "method" ], "properties": { "id": { "type": "string" }, "path": { "type": "string" }, "method": { "type": "string" }, "entity": { "type": "string" }, "action": { "type": "string" }, "summary": { "type": "string" }, "description": { "type": "string" }, "tags": { "type": "array", "items": { "type": "string" } }, "parameters": { "type": "array", "items": {} }, "requestBody": {}, "response": {}, "response_schema": {}, "relations": { "type": "array", "items": {} }, "source": { "type": "string" } } } }, "error": { "type": "string" } } } }, "multipart/form-data": { "schema": { "type": "object", "properties": { "endpoints": { "type": "array", "items": { "type": "object", "required": [ "id", "path", "method" ], "properties": { "id": { "type": "string" }, "path": { "type": "string" }, "method": { "type": "string" }, "entity": { "type": "string" }, "action": { "type": "string" }, "summary": { "type": "string" }, "description": { "type": "string" }, "tags": { "type": "array", "items": { "type": "string" } }, "parameters": { "type": "array", "items": {} }, "requestBody": {}, "response": {}, "response_schema": {}, "relations": { "type": "array", "items": {} }, "source": { "type": "string" } } } }, "error": { "type": "string" } } } }, "text/plain": { "schema": { "type": "object", "properties": { "endpoints": { "type": "array", "items": { "type": "object", "required": [ "id", "path", "method" ], "properties": { "id": { "type": "string" }, "path": { "type": "string" }, "method": { "type": "string" }, "entity": { "type": "string" }, "action": { "type": "string" }, "summary": { "type": "string" }, "description": { "type": "string" }, "tags": { "type": "array", "items": { "type": "string" } }, "parameters": { "type": "array", "items": {} }, "requestBody": {}, "response": {}, "response_schema": {}, "relations": { "type": "array", "items": {} }, "source": { "type": "string" } } } }, "error": { "type": "string" } } } } } } }, "operationId": "getApiConnectorsByIdEndpoints", "summary": "Liste des endpoints du connecteur", "description": "Retourne tous les endpoints decouverts pour ce connecteur. Peut etre filtre par entite ou action.", "tags": [ "connectors" ] }, "post": { "parameters": [ { "schema": { "type": "string" }, "in": "path", "name": "id", "required": true } ], "operationId": "postApiConnectorsByIdEndpoints", "summary": "Creer un endpoint custom", "description": "Ajoute un endpoint personnalise a un connecteur custom (mode Postman)", "tags": [ "endpoints" ], "requestBody": { "required": true, "content": { "application/json": { "schema": { "type": "object", "required": [ "path", "method" ], "properties": { "path": { "description": "Chemin de l'endpoint (ex: /users/{id})", "type": "string" }, "method": { "description": "Methode HTTP (GET, POST, PUT, PATCH, DELETE)", "type": "string" }, "entity": { "description": "Entite (ex: user, project)", "type": "string" }, "action": { "description": "Action (list, get, create, update, delete)", "type": "string" }, "summary": { "description": "Description courte", "type": "string" }, "description": { "description": "Description detaillee", "type": "string" }, "request_schema": { "description": "Schema du body de requete" }, "response_schema": { "description": "Schema de la reponse" }, "parameters": { "description": "Parametres query/path", "type": "array", "items": {} } } } }, "multipart/form-data": { "schema": { "type": "object", "required": [ "path", "method" ], "properties": { "path": { "description": "Chemin de l'endpoint (ex: /users/{id})", "type": "string" }, "method": { "description": "Methode HTTP (GET, POST, PUT, PATCH, DELETE)", "type": "string" }, "entity": { "description": "Entite (ex: user, project)", "type": "string" }, "action": { "description": "Action (list, get, create, update, delete)", "type": "string" }, "summary": { "description": "Description courte", "type": "string" }, "description": { "description": "Description detaillee", "type": "string" }, "request_schema": { "description": "Schema du body de requete" }, "response_schema": { "description": "Schema de la reponse" }, "parameters": { "description": "Parametres query/path", "type": "array", "items": {} } } } }, "text/plain": { "schema": { "type": "object", "required": [ "path", "method" ], "properties": { "path": { "description": "Chemin de l'endpoint (ex: /users/{id})", "type": "string" }, "method": { "description": "Methode HTTP (GET, POST, PUT, PATCH, DELETE)", "type": "string" }, "entity": { "description": "Entite (ex: user, project)", "type": "string" }, "action": { "description": "Action (list, get, create, update, delete)", "type": "string" }, "summary": { "description": "Description courte", "type": "string" }, "description": { "description": "Description detaillee", "type": "string" }, "request_schema": { "description": "Schema du body de requete" }, "response_schema": { "description": "Schema de la reponse" }, "parameters": { "description": "Parametres query/path", "type": "array", "items": {} } } } } } }, "responses": { "200": {} } } }, "/api/endpoints/{id}": { "put": { "parameters": [ { "schema": { "type": "string" }, "in": "path", "name": "id", "required": true } ], "operationId": "putApiEndpointsById", "summary": "Modifier un endpoint", "description": "Met a jour un endpoint custom", "tags": [ "endpoints" ], "requestBody": { "required": true, "content": { "application/json": { "schema": { "type": "object", "properties": { "path": { "type": "string" }, "method": { "type": "string" }, "entity": { "type": "string" }, "action": { "type": "string" }, "summary": { "type": "string" }, "description": { "type": "string" }, "request_schema": {}, "response_schema": {}, "parameters": { "type": "array", "items": {} } } } }, "multipart/form-data": { "schema": { "type": "object", "properties": { "path": { "type": "string" }, "method": { "type": "string" }, "entity": { "type": "string" }, "action": { "type": "string" }, "summary": { "type": "string" }, "description": { "type": "string" }, "request_schema": {}, "response_schema": {}, "parameters": { "type": "array", "items": {} } } } }, "text/plain": { "schema": { "type": "object", "properties": { "path": { "type": "string" }, "method": { "type": "string" }, "entity": { "type": "string" }, "action": { "type": "string" }, "summary": { "type": "string" }, "description": { "type": "string" }, "request_schema": {}, "response_schema": {}, "parameters": { "type": "array", "items": {} } } } } } }, "responses": { "200": {} } }, "delete": { "parameters": [ { "schema": { "type": "string" }, "in": "path", "name": "id", "required": true } ], "operationId": "deleteApiEndpointsById", "summary": "Supprimer un endpoint", "description": "Supprime un endpoint custom", "tags": [ "endpoints" ], "responses": { "200": {} } }, "get": { "parameters": [ { "schema": { "type": "string" }, "in": "path", "name": "id", "required": true } ], "operationId": "getApiEndpointsById", "summary": "Détail d'un endpoint", "tags": [ "endpoints" ], "responses": { "200": {} } } }, "/api/discover/{id}": { "post": { "parameters": [ { "schema": { "type": "string" }, "in": "path", "name": "id", "required": true } ], "responses": { "200": { "content": { "application/json": { "schema": { "type": "object", "properties": { "success": { "type": "boolean" }, "message": { "type": "string" }, "source": { "type": "string" }, "endpoint": {}, "relations_found": { "type": "number" }, "discovered": { "type": "array", "items": { "type": "string" } }, "error": { "type": "string" } } } }, "multipart/form-data": { "schema": { "type": "object", "properties": { "success": { "type": "boolean" }, "message": { "type": "string" }, "source": { "type": "string" }, "endpoint": {}, "relations_found": { "type": "number" }, "discovered": { "type": "array", "items": { "type": "string" } }, "error": { "type": "string" } } } }, "text/plain": { "schema": { "type": "object", "properties": { "success": { "type": "boolean" }, "message": { "type": "string" }, "source": { "type": "string" }, "endpoint": {}, "relations_found": { "type": "number" }, "discovered": { "type": "array", "items": { "type": "string" } }, "error": { "type": "string" } } } } } } }, "operationId": "postApiDiscoverById", "summary": "Decouvrir le schema du connecteur", "description": "Lance la decouverte automatique du schema API.\n\n**Modes:**\n- `openapi_url`: Importe depuis une spec OpenAPI\n- `path` + `method`: Decouvre un endpoint specifique\n- `discover_all`: Tente de decouvrir les endpoints communs\n\nLa decouverte analyse les reponses pour:\n- Detecter les types de champs\n- Trouver les relations (liens vers autres endpoints)\n- Identifier les entites et actions", "security": [ { "bearerAuth": [] } ], "tags": [ "connectors" ], "requestBody": { "required": true, "content": { "application/json": { "schema": { "type": "object", "properties": { "openapi_url": { "description": "URL du fichier OpenAPI/Swagger", "type": "string" }, "openapi_spec": { "description": "OpenAPI spec JSON direct (pour fichiers volumineux)" }, "path": { "description": "Chemin a decouvrir", "examples": [ "/projects", "/users" ], "type": "string" }, "method": { "description": "Methode HTTP", "default": "GET", "type": "string" }, "discover_all": { "description": "Tenter decouverte automatique", "type": "boolean" } } } }, "multipart/form-data": { "schema": { "type": "object", "properties": { "openapi_url": { "description": "URL du fichier OpenAPI/Swagger", "type": "string" }, "openapi_spec": { "description": "OpenAPI spec JSON direct (pour fichiers volumineux)" }, "path": { "description": "Chemin a decouvrir", "examples": [ "/projects", "/users" ], "type": "string" }, "method": { "description": "Methode HTTP", "default": "GET", "type": "string" }, "discover_all": { "description": "Tenter decouverte automatique", "type": "boolean" } } } }, "text/plain": { "schema": { "type": "object", "properties": { "openapi_url": { "description": "URL du fichier OpenAPI/Swagger", "type": "string" }, "openapi_spec": { "description": "OpenAPI spec JSON direct (pour fichiers volumineux)" }, "path": { "description": "Chemin a decouvrir", "examples": [ "/projects", "/users" ], "type": "string" }, "method": { "description": "Methode HTTP", "default": "GET", "type": "string" }, "discover_all": { "description": "Tenter decouverte automatique", "type": "boolean" } } } } } } } }, "/api/user/connectors/{id}": { "get": { "parameters": [ { "schema": { "type": "string" }, "in": "path", "name": "id", "required": true } ], "operationId": "getApiUserConnectorsById", "summary": "Mon statut de connexion", "security": [ { "bearerAuth": [] } ], "tags": [ "user" ], "responses": { "200": {} } } }, "/api/user/connectors/{id}/auth": { "get": { "parameters": [ { "schema": { "type": "string" }, "in": "path", "name": "id", "required": true } ], "operationId": "getApiUserConnectorsByIdAuth", "summary": "Obtenir URL d'auth ou instructions", "description": "Pour OAuth2: retourne l'URL d'autorisation. Pour autres: retourne les instructions.", "security": [ { "bearerAuth": [] } ], "tags": [ "user" ], "responses": { "200": {} } }, "delete": { "parameters": [ { "schema": { "type": "string" }, "in": "path", "name": "id", "required": true } ], "operationId": "deleteApiUserConnectorsByIdAuth", "summary": "Révoquer mon token", "security": [ { "bearerAuth": [] } ], "tags": [ "user" ], "responses": { "200": {} } } }, "/api/connectors/{id}/callback": { "get": { "parameters": [ { "schema": { "type": "string" }, "in": "path", "name": "id", "required": true }, { "schema": { "type": "string" }, "in": "query", "name": "code", "required": false }, { "schema": { "type": "string" }, "in": "query", "name": "error", "required": false }, { "schema": { "type": "string" }, "in": "query", "name": "state", "required": false } ], "operationId": "getApiConnectorsByIdCallback", "summary": "OAuth callback", "description": "Endpoint appelé par le provider OAuth après autorisation", "tags": [ "user" ], "responses": { "200": {} } } }, "/api/user/connectors/{id}/token": { "post": { "parameters": [ { "schema": { "type": "string" }, "in": "path", "name": "id", "required": true } ], "operationId": "postApiUserConnectorsByIdToken", "summary": "Définir mon token", "description": "Enregistrer un token API pour ce connecteur", "security": [ { "bearerAuth": [] } ], "tags": [ "user" ], "requestBody": { "required": true, "content": { "application/json": { "schema": { "type": "object", "required": [ "token" ], "properties": { "token": { "description": "Le token ou clé API", "type": "string" }, "type": { "description": "Type: api_key ou bearer", "examples": [ "api_key", "bearer" ], "type": "string" } } } }, "multipart/form-data": { "schema": { "type": "object", "required": [ "token" ], "properties": { "token": { "description": "Le token ou clé API", "type": "string" }, "type": { "description": "Type: api_key ou bearer", "examples": [ "api_key", "bearer" ], "type": "string" } } } }, "text/plain": { "schema": { "type": "object", "required": [ "token" ], "properties": { "token": { "description": "Le token ou clé API", "type": "string" }, "type": { "description": "Type: api_key ou bearer", "examples": [ "api_key", "bearer" ], "type": "string" } } } } } }, "responses": { "200": {} } } }, "/api/connectors/{id}/token": { "post": { "parameters": [ { "schema": { "type": "string" }, "in": "path", "name": "id", "required": true } ], "operationId": "postApiConnectorsByIdToken", "summary": "Définir token système (admin)", "description": "Token partagé sans user_id", "tags": [ "connectors" ], "requestBody": { "required": true, "content": { "application/json": { "schema": { "type": "object", "required": [ "token" ], "properties": { "token": { "type": "string" }, "type": { "type": "string" } } } }, "multipart/form-data": { "schema": { "type": "object", "required": [ "token" ], "properties": { "token": { "type": "string" }, "type": { "type": "string" } } } }, "text/plain": { "schema": { "type": "object", "required": [ "token" ], "properties": { "token": { "type": "string" }, "type": { "type": "string" } } } } } }, "responses": { "200": {} } } }, "/api/audit/logs": { "get": { "parameters": [ { "description": "Filtrer par utilisateur", "schema": { "type": "string" }, "in": "query", "name": "user_id", "required": false }, { "description": "Filtrer par connecteur", "schema": { "type": "string" }, "in": "query", "name": "connector_id", "required": false }, { "description": "Filtrer par action (auth.login, connector.create, etc.)", "schema": { "type": "string" }, "in": "query", "name": "action", "required": false }, { "description": "Filtrer par ressource (connector, endpoint, token, user)", "schema": { "type": "string" }, "in": "query", "name": "resource", "required": false }, { "description": "Limite (default: 100)", "schema": { "type": "string" }, "in": "query", "name": "limit", "required": false } ], "responses": { "200": { "content": { "application/json": { "schema": { "type": "object", "properties": { "logs": { "type": "array", "items": { "type": "object", "required": [ "id", "user_id", "connector_id", "action", "resource", "resource_id", "details", "ip_address", "user_agent", "created_at" ], "properties": { "id": { "type": "string" }, "user_id": { "anyOf": [ { "type": "string" }, { "type": "null" } ] }, "connector_id": { "anyOf": [ { "type": "string" }, { "type": "null" } ] }, "action": { "type": "string" }, "resource": { "type": "string" }, "resource_id": { "anyOf": [ { "type": "string" }, { "type": "null" } ] }, "details": { "anyOf": [ {}, { "type": "null" } ] }, "ip_address": { "anyOf": [ { "type": "string" }, { "type": "null" } ] }, "user_agent": { "anyOf": [ { "type": "string" }, { "type": "null" } ] }, "created_at": { "type": "string" } } } }, "error": { "type": "string" } } } }, "multipart/form-data": { "schema": { "type": "object", "properties": { "logs": { "type": "array", "items": { "type": "object", "required": [ "id", "user_id", "connector_id", "action", "resource", "resource_id", "details", "ip_address", "user_agent", "created_at" ], "properties": { "id": { "type": "string" }, "user_id": { "anyOf": [ { "type": "string" }, { "type": "null" } ] }, "connector_id": { "anyOf": [ { "type": "string" }, { "type": "null" } ] }, "action": { "type": "string" }, "resource": { "type": "string" }, "resource_id": { "anyOf": [ { "type": "string" }, { "type": "null" } ] }, "details": { "anyOf": [ {}, { "type": "null" } ] }, "ip_address": { "anyOf": [ { "type": "string" }, { "type": "null" } ] }, "user_agent": { "anyOf": [ { "type": "string" }, { "type": "null" } ] }, "created_at": { "type": "string" } } } }, "error": { "type": "string" } } } }, "text/plain": { "schema": { "type": "object", "properties": { "logs": { "type": "array", "items": { "type": "object", "required": [ "id", "user_id", "connector_id", "action", "resource", "resource_id", "details", "ip_address", "user_agent", "created_at" ], "properties": { "id": { "type": "string" }, "user_id": { "anyOf": [ { "type": "string" }, { "type": "null" } ] }, "connector_id": { "anyOf": [ { "type": "string" }, { "type": "null" } ] }, "action": { "type": "string" }, "resource": { "type": "string" }, "resource_id": { "anyOf": [ { "type": "string" }, { "type": "null" } ] }, "details": { "anyOf": [ {}, { "type": "null" } ] }, "ip_address": { "anyOf": [ { "type": "string" }, { "type": "null" } ] }, "user_agent": { "anyOf": [ { "type": "string" }, { "type": "null" } ] }, "created_at": { "type": "string" } } } }, "error": { "type": "string" } } } } } } }, "operationId": "getApiAuditLogs", "summary": "Liste des logs d'audit", "description": "Récupère les logs d'audit avec filtres optionnels", "security": [ { "bearerAuth": [] } ], "tags": [ "audit" ] } }, "/api/audit/logs/{id}": { "get": { "parameters": [ { "schema": { "type": "string" }, "in": "path", "name": "id", "required": true } ], "operationId": "getApiAuditLogsById", "summary": "Détail d'un log d'audit", "security": [ { "bearerAuth": [] } ], "tags": [ "audit" ], "responses": { "200": {} } } }, "/api/audit/stats": { "get": { "parameters": [ { "schema": { "type": "string" }, "in": "query", "name": "user_id", "required": false }, { "schema": { "type": "string" }, "in": "query", "name": "connector_id", "required": false }, { "description": "Date ISO depuis laquelle compter", "schema": { "type": "string" }, "in": "query", "name": "since", "required": false } ], "operationId": "getApiAuditStats", "summary": "Statistiques d'audit", "description": "Statistiques globales sur les actions effectuées", "security": [ { "bearerAuth": [] } ], "tags": [ "audit" ], "responses": { "200": {} } } }, "/api/connectors/{id}/logs": { "get": { "parameters": [ { "schema": { "type": "string" }, "in": "path", "name": "id", "required": true }, { "description": "Limite (default: 50)", "schema": { "type": "string" }, "in": "query", "name": "limit", "required": false } ], "operationId": "getApiConnectorsByIdLogs", "summary": "Logs d'un connecteur", "description": "Récupère les logs d'audit pour un connecteur spécifique", "tags": [ "audit" ], "responses": { "200": {} } } }, "/api/endpoints/{id}/versions": { "get": { "parameters": [ { "schema": { "type": "string" }, "in": "path", "name": "id", "required": true }, { "description": "Limite (default: 50)", "schema": { "type": "string" }, "in": "query", "name": "limit", "required": false } ], "operationId": "getApiEndpointsByIdVersions", "summary": "Historique des versions", "description": "Liste toutes les versions d'un endpoint", "tags": [ "endpoints" ], "responses": { "200": {} } } }, "/api/endpoints/{id}/versions/{version}": { "get": { "parameters": [ { "schema": { "type": "string" }, "in": "path", "name": "id", "required": true }, { "description": "Numéro de version", "schema": { "type": "string" }, "in": "path", "name": "version", "required": true } ], "operationId": "getApiEndpointsByIdVersionsByVersion", "summary": "Détail d'une version", "tags": [ "endpoints" ], "responses": { "200": {} } } }, "/api/endpoints/{id}/rollback/{version}": { "post": { "parameters": [ { "schema": { "type": "string" }, "in": "path", "name": "id", "required": true }, { "description": "Version cible", "schema": { "type": "string" }, "in": "path", "name": "version", "required": true } ], "operationId": "postApiEndpointsByIdRollbackByVersion", "summary": "Rollback vers une version", "description": "Restaure un endpoint à une version antérieure", "security": [ { "bearerAuth": [] } ], "tags": [ "endpoints" ], "responses": { "200": {} } } }, "/api/endpoints/{id}/diff/{v1}/{v2}": { "get": { "parameters": [ { "schema": { "type": "string" }, "in": "path", "name": "id", "required": true }, { "description": "Version 1", "schema": { "type": "string" }, "in": "path", "name": "v1", "required": true }, { "description": "Version 2", "schema": { "type": "string" }, "in": "path", "name": "v2", "required": true } ], "operationId": "getApiEndpointsByIdDiffByV1ByV2", "summary": "Diff entre deux versions", "description": "Compare deux versions d'un endpoint", "tags": [ "endpoints" ], "responses": { "200": {} } } }, "/api/user/instances": { "get": { "operationId": "getApiUserInstances", "summary": "Lister mes instances", "description": "Liste toutes les instances de connecteurs de l'utilisateur", "security": [ { "bearerAuth": [] } ], "tags": [ "instances" ], "responses": { "200": {} } }, "post": { "parameters": [], "operationId": "postApiUserInstances", "summary": "Créer une instance", "description": "Crée une nouvelle instance d'un type de connecteur (ex: second compte Jellyfin)", "security": [ { "bearerAuth": [] } ], "tags": [ "instances" ], "requestBody": { "required": true, "content": { "application/json": { "schema": { "type": "object", "required": [ "connector_type", "name" ], "properties": { "connector_type": { "description": "Nom du type de connecteur (jellyfin, github, etc.)", "type": "string" }, "name": { "description": "Nom personnalisé (ex: \"Jellyfin Famille\")", "type": "string" }, "base_url": { "description": "URL de base (optionnel, override du type)", "type": "string" }, "api_key": { "description": "Clé API (pour auth_type: api_key)", "type": "string" }, "access_token": { "description": "Token d'accès (pour auth_type: bearer)", "type": "string" } } } }, "multipart/form-data": { "schema": { "type": "object", "required": [ "connector_type", "name" ], "properties": { "connector_type": { "description": "Nom du type de connecteur (jellyfin, github, etc.)", "type": "string" }, "name": { "description": "Nom personnalisé (ex: \"Jellyfin Famille\")", "type": "string" }, "base_url": { "description": "URL de base (optionnel, override du type)", "type": "string" }, "api_key": { "description": "Clé API (pour auth_type: api_key)", "type": "string" }, "access_token": { "description": "Token d'accès (pour auth_type: bearer)", "type": "string" } } } }, "text/plain": { "schema": { "type": "object", "required": [ "connector_type", "name" ], "properties": { "connector_type": { "description": "Nom du type de connecteur (jellyfin, github, etc.)", "type": "string" }, "name": { "description": "Nom personnalisé (ex: \"Jellyfin Famille\")", "type": "string" }, "base_url": { "description": "URL de base (optionnel, override du type)", "type": "string" }, "api_key": { "description": "Clé API (pour auth_type: api_key)", "type": "string" }, "access_token": { "description": "Token d'accès (pour auth_type: bearer)", "type": "string" } } } } } }, "responses": { "200": {} } } }, "/api/user/instances/{id}": { "get": { "parameters": [ { "schema": { "type": "string" }, "in": "path", "name": "id", "required": true } ], "operationId": "getApiUserInstancesById", "summary": "Détails d'une instance", "security": [ { "bearerAuth": [] } ], "tags": [ "instances" ], "responses": { "200": {} } }, "put": { "parameters": [ { "schema": { "type": "string" }, "in": "path", "name": "id", "required": true } ], "operationId": "putApiUserInstancesById", "summary": "Modifier une instance", "security": [ { "bearerAuth": [] } ], "tags": [ "instances" ], "requestBody": { "required": true, "content": { "application/json": { "schema": { "type": "object", "properties": { "name": { "description": "Nouveau nom", "type": "string" }, "base_url": { "description": "Nouvelle URL de base", "type": "string" }, "api_key": { "description": "Nouvelle clé API", "type": "string" }, "access_token": { "description": "Nouveau token", "type": "string" } } } }, "multipart/form-data": { "schema": { "type": "object", "properties": { "name": { "description": "Nouveau nom", "type": "string" }, "base_url": { "description": "Nouvelle URL de base", "type": "string" }, "api_key": { "description": "Nouvelle clé API", "type": "string" }, "access_token": { "description": "Nouveau token", "type": "string" } } } }, "text/plain": { "schema": { "type": "object", "properties": { "name": { "description": "Nouveau nom", "type": "string" }, "base_url": { "description": "Nouvelle URL de base", "type": "string" }, "api_key": { "description": "Nouvelle clé API", "type": "string" }, "access_token": { "description": "Nouveau token", "type": "string" } } } } } }, "responses": { "200": {} } }, "delete": { "parameters": [ { "schema": { "type": "string" }, "in": "path", "name": "id", "required": true } ], "operationId": "deleteApiUserInstancesById", "summary": "Supprimer une instance", "security": [ { "bearerAuth": [] } ], "tags": [ "instances" ], "responses": { "200": {} } } }, "/api/user/instances/{id}/default": { "post": { "parameters": [ { "schema": { "type": "string" }, "in": "path", "name": "id", "required": true } ], "operationId": "postApiUserInstancesByIdDefault", "summary": "Définir comme instance par défaut", "description": "Cette instance sera utilisée par défaut pour ce type de connecteur", "security": [ { "bearerAuth": [] } ], "tags": [ "instances" ], "responses": { "200": {} } } }, "/api/ssh/execute": { "post": { "parameters": [], "responses": { "200": { "content": { "application/json": { "schema": { "type": "object", "properties": { "success": { "type": "boolean" }, "stdout": { "type": "string" }, "stderr": { "type": "string" }, "exit_code": { "type": "number" }, "duration_ms": { "type": "number" }, "error": { "type": "string" }, "warning": { "type": "boolean" }, "message": { "type": "string" }, "command": { "type": "string" } }, "required": [ "success" ] } }, "multipart/form-data": { "schema": { "type": "object", "properties": { "success": { "type": "boolean" }, "stdout": { "type": "string" }, "stderr": { "type": "string" }, "exit_code": { "type": "number" }, "duration_ms": { "type": "number" }, "error": { "type": "string" }, "warning": { "type": "boolean" }, "message": { "type": "string" }, "command": { "type": "string" } }, "required": [ "success" ] } }, "text/plain": { "schema": { "type": "object", "properties": { "success": { "type": "boolean" }, "stdout": { "type": "string" }, "stderr": { "type": "string" }, "exit_code": { "type": "number" }, "duration_ms": { "type": "number" }, "error": { "type": "string" }, "warning": { "type": "boolean" }, "message": { "type": "string" }, "command": { "type": "string" } }, "required": [ "success" ] } } } } }, "operationId": "postApiSshExecute", "summary": "Execute SSH command", "description": "Execute a command on a remote server via SSH.\n\n**Dangerous commands** (rm -rf, mkfs, dd, shutdown, etc.) require `force: true`.\n\n**Timeout:** Max 5 minutes (300000ms).\n\n**Examples:**\n```json\n{\"instance_id\": \"uuid\", \"command\": \"ls -la\"}\n{\"instance_id\": \"uuid\", \"command\": \"df -h && free -m\"}\n{\"instance_id\": \"uuid\", \"command\": \"cat /etc/hostname\", \"cwd\": \"/\"}\n```", "security": [ { "bearerAuth": [] } ], "tags": [ "ssh" ], "requestBody": { "required": true, "content": { "application/json": { "schema": { "type": "object", "required": [ "instance_id", "command" ], "properties": { "instance_id": { "description": "SSH instance ID", "type": "string" }, "command": { "description": "Command to execute", "type": "string" }, "cwd": { "description": "Working directory", "type": "string" }, "timeout": { "description": "Timeout in ms (max 300000)", "default": 30000, "type": "number" }, "force": { "description": "Force dangerous command execution", "type": "boolean" } } } }, "multipart/form-data": { "schema": { "type": "object", "required": [ "instance_id", "command" ], "properties": { "instance_id": { "description": "SSH instance ID", "type": "string" }, "command": { "description": "Command to execute", "type": "string" }, "cwd": { "description": "Working directory", "type": "string" }, "timeout": { "description": "Timeout in ms (max 300000)", "default": 30000, "type": "number" }, "force": { "description": "Force dangerous command execution", "type": "boolean" } } } }, "text/plain": { "schema": { "type": "object", "required": [ "instance_id", "command" ], "properties": { "instance_id": { "description": "SSH instance ID", "type": "string" }, "command": { "description": "Command to execute", "type": "string" }, "cwd": { "description": "Working directory", "type": "string" }, "timeout": { "description": "Timeout in ms (max 300000)", "default": 30000, "type": "number" }, "force": { "description": "Force dangerous command execution", "type": "boolean" } } } } } } } }, "/api/ssh/test": { "post": { "parameters": [], "responses": { "200": { "content": { "application/json": { "schema": { "type": "object", "properties": { "success": { "type": "boolean" }, "message": { "type": "string" }, "fingerprint": { "type": "string" } }, "required": [ "success", "message" ] } }, "multipart/form-data": { "schema": { "type": "object", "properties": { "success": { "type": "boolean" }, "message": { "type": "string" }, "fingerprint": { "type": "string" } }, "required": [ "success", "message" ] } }, "text/plain": { "schema": { "type": "object", "properties": { "success": { "type": "boolean" }, "message": { "type": "string" }, "fingerprint": { "type": "string" } }, "required": [ "success", "message" ] } } } } }, "operationId": "postApiSshTest", "summary": "Test SSH connection", "description": "Test SSH connection without saving. Returns server fingerprint on success.", "security": [ { "bearerAuth": [] } ], "tags": [ "ssh" ], "requestBody": { "required": true, "content": { "application/json": { "schema": { "type": "object", "required": [ "host", "username" ], "properties": { "host": { "description": "Hostname or IP", "type": "string" }, "port": { "description": "SSH port (default: 22)", "default": 22, "type": "number" }, "username": { "description": "SSH username", "type": "string" }, "password": { "description": "Password (for password auth)", "type": "string" }, "private_key": { "description": "Private key PEM (for key auth)", "type": "string" }, "auth_method": { "description": "password or key", "type": "string" } } } }, "multipart/form-data": { "schema": { "type": "object", "required": [ "host", "username" ], "properties": { "host": { "description": "Hostname or IP", "type": "string" }, "port": { "description": "SSH port (default: 22)", "default": 22, "type": "number" }, "username": { "description": "SSH username", "type": "string" }, "password": { "description": "Password (for password auth)", "type": "string" }, "private_key": { "description": "Private key PEM (for key auth)", "type": "string" }, "auth_method": { "description": "password or key", "type": "string" } } } }, "text/plain": { "schema": { "type": "object", "required": [ "host", "username" ], "properties": { "host": { "description": "Hostname or IP", "type": "string" }, "port": { "description": "SSH port (default: 22)", "default": 22, "type": "number" }, "username": { "description": "SSH username", "type": "string" }, "password": { "description": "Password (for password auth)", "type": "string" }, "private_key": { "description": "Private key PEM (for key auth)", "type": "string" }, "auth_method": { "description": "password or key", "type": "string" } } } } } } } }, "/api/ssh/upload": { "post": { "parameters": [], "responses": { "200": { "content": { "application/json": { "schema": { "type": "object", "properties": { "success": { "type": "boolean" }, "message": { "type": "string" } }, "required": [ "success", "message" ] } }, "multipart/form-data": { "schema": { "type": "object", "properties": { "success": { "type": "boolean" }, "message": { "type": "string" } }, "required": [ "success", "message" ] } }, "text/plain": { "schema": { "type": "object", "properties": { "success": { "type": "boolean" }, "message": { "type": "string" } }, "required": [ "success", "message" ] } } } } }, "operationId": "postApiSshUpload", "summary": "Upload file via SSH", "description": "Upload a file to the remote server. For text files only (use SFTP for binary).", "security": [ { "bearerAuth": [] } ], "tags": [ "ssh" ], "requestBody": { "required": true, "content": { "application/json": { "schema": { "type": "object", "required": [ "instance_id", "content", "remote_path" ], "properties": { "instance_id": { "description": "SSH instance ID", "type": "string" }, "content": { "description": "File content (text or base64)", "type": "string" }, "remote_path": { "description": "Destination path on remote", "type": "string" }, "mode": { "description": "File permissions (e.g., 755)", "examples": [ "644", "755" ], "type": "string" }, "encoding": { "description": "utf8 or base64", "default": "utf8", "type": "string" } } } }, "multipart/form-data": { "schema": { "type": "object", "required": [ "instance_id", "content", "remote_path" ], "properties": { "instance_id": { "description": "SSH instance ID", "type": "string" }, "content": { "description": "File content (text or base64)", "type": "string" }, "remote_path": { "description": "Destination path on remote", "type": "string" }, "mode": { "description": "File permissions (e.g., 755)", "examples": [ "644", "755" ], "type": "string" }, "encoding": { "description": "utf8 or base64", "default": "utf8", "type": "string" } } } }, "text/plain": { "schema": { "type": "object", "required": [ "instance_id", "content", "remote_path" ], "properties": { "instance_id": { "description": "SSH instance ID", "type": "string" }, "content": { "description": "File content (text or base64)", "type": "string" }, "remote_path": { "description": "Destination path on remote", "type": "string" }, "mode": { "description": "File permissions (e.g., 755)", "examples": [ "644", "755" ], "type": "string" }, "encoding": { "description": "utf8 or base64", "default": "utf8", "type": "string" } } } } } } } }, "/api/ssh/download": { "post": { "parameters": [], "responses": { "200": { "content": { "application/json": { "schema": { "type": "object", "properties": { "success": { "type": "boolean" }, "content": { "type": "string" }, "error": { "type": "string" } }, "required": [ "success" ] } }, "multipart/form-data": { "schema": { "type": "object", "properties": { "success": { "type": "boolean" }, "content": { "type": "string" }, "error": { "type": "string" } }, "required": [ "success" ] } }, "text/plain": { "schema": { "type": "object", "properties": { "success": { "type": "boolean" }, "content": { "type": "string" }, "error": { "type": "string" } }, "required": [ "success" ] } } } } }, "operationId": "postApiSshDownload", "summary": "Download file via SSH", "description": "Download a file from the remote server. Use `tail` to get only the last N lines.", "security": [ { "bearerAuth": [] } ], "tags": [ "ssh" ], "requestBody": { "required": true, "content": { "application/json": { "schema": { "type": "object", "required": [ "instance_id", "remote_path" ], "properties": { "instance_id": { "description": "SSH instance ID", "type": "string" }, "remote_path": { "description": "File path on remote", "type": "string" }, "tail": { "description": "Get only last N lines", "type": "number" } } } }, "multipart/form-data": { "schema": { "type": "object", "required": [ "instance_id", "remote_path" ], "properties": { "instance_id": { "description": "SSH instance ID", "type": "string" }, "remote_path": { "description": "File path on remote", "type": "string" }, "tail": { "description": "Get only last N lines", "type": "number" } } } }, "text/plain": { "schema": { "type": "object", "required": [ "instance_id", "remote_path" ], "properties": { "instance_id": { "description": "SSH instance ID", "type": "string" }, "remote_path": { "description": "File path on remote", "type": "string" }, "tail": { "description": "Get only last N lines", "type": "number" } } } } } } } }, "/api/ssh/setup-key": { "post": { "parameters": [], "responses": { "200": { "content": { "application/json": { "schema": { "type": "object", "properties": { "success": { "type": "boolean" }, "message": { "type": "string" } }, "required": [ "success", "message" ] } }, "multipart/form-data": { "schema": { "type": "object", "properties": { "success": { "type": "boolean" }, "message": { "type": "string" } }, "required": [ "success", "message" ] } }, "text/plain": { "schema": { "type": "object", "properties": { "success": { "type": "boolean" }, "message": { "type": "string" } }, "required": [ "success", "message" ] } } } } }, "operationId": "postApiSshSetup-key", "summary": "Setup auto SSH key", "description": "Generate an SSH key pair, install it on the remote server using the provided password, then remove the password from storage.\n\nAfter this, the instance will authenticate using the key only.\n\n**Flow:**\n1. Generate RSA 4096 key pair\n2. Connect with password\n3. Add public key to ~/.ssh/authorized_keys\n4. Store encrypted private key\n5. Remove password from DB", "security": [ { "bearerAuth": [] } ], "tags": [ "ssh" ], "requestBody": { "required": true, "content": { "application/json": { "schema": { "type": "object", "required": [ "instance_id", "password" ], "properties": { "instance_id": { "description": "SSH instance ID", "type": "string" }, "password": { "description": "Current password to authenticate initial setup", "type": "string" } } } }, "multipart/form-data": { "schema": { "type": "object", "required": [ "instance_id", "password" ], "properties": { "instance_id": { "description": "SSH instance ID", "type": "string" }, "password": { "description": "Current password to authenticate initial setup", "type": "string" } } } }, "text/plain": { "schema": { "type": "object", "required": [ "instance_id", "password" ], "properties": { "instance_id": { "description": "SSH instance ID", "type": "string" }, "password": { "description": "Current password to authenticate initial setup", "type": "string" } } } } } } } } } }