---
title: Référence API
description: Documentation détaillée de tous les points de terminaison de l'API Memegoat.
---

## 📖 Référence API

Cette page documente tous les points de terminaison disponibles sur l'API Memegoat. L'URL de base de l'API est `https://api.memegoat.fr`.

<Callout type="info">
  L'authentification est gérée via des **cookies HttpOnly sécurisés** (`iron-session`). Les tokens ne sont pas exposés dans le corps des réponses après connexion pour une sécurité maximale.
</Callout>

### 🔐 Authentification (`/auth`)

<Accordions>
  <Accordion title="POST /auth/register">
    Inscrit un nouvel utilisateur.

    **Corps de la requête (JSON) :**
    - `username` (string, max: 32) : Nom d'utilisateur unique.
    - `email` (string) : Adresse email valide.
    - `password` (string, min: 8) : Mot de passe.
    - `displayName` (string, optional, max: 32) : Nom d'affichage.

    **Réponses :**
    - `201 Created` : Utilisateur créé.
    - `400 Bad Request` : Validation échouée ou utilisateur déjà existant.

    ```json
    {
      "username": "goat_user",
      "email": "user@memegoat.fr",
      "password": "strong-password",
      "displayName": "Le Bouc"
    }
    ```
  </Accordion>

  <Accordion title="POST /auth/login">
    Authentifie un utilisateur et retourne les jetons de session. Si la 2FA est activée, retourne un indicateur.

    **Corps de la requête :**
    - `email` (string)
    - `password` (string)

    **Réponses :**
    - `200 OK` : Connexion réussie.
      ```json
      {
        "message": "User logged in successfully",
        "userId": "uuid-v4"
      }
      ```
    - `200 OK` (2FA requise) :
      ```json
      {
        "message": "2FA required",
        "requires2FA": true,
        "userId": "uuid-v4"
      }
      ```
    - `401 Unauthorized` : Identifiants invalides.

    *Note: L'access_token et le refresh_token sont stockés dans un cookie HttpOnly chiffré.*
  </Accordion>

  <Accordion title="POST /auth/verify-2fa">
    Finalise la connexion si la 2FA est requise.

    **Corps de la requête :**
    - `userId` (uuid) : ID de l'utilisateur.
    - `token` (string) : Code TOTP à 6 chiffres.

    **Réponses :**
    - `200 OK` : Vérification réussie, session établie.
    - `401 Unauthorized` : Token invalide ou utilisateur non autorisé.
  </Accordion>

  <Accordion title="POST /auth/refresh">
    Obtient un nouvel `access_token` à partir du `refresh_token` stocké dans la session.
    Met à jour automatiquement le cookie de session.

    **Réponses :**
    - `200 OK` : Token rafraîchi.
    - `401 Unauthorized` : Refresh token absent ou invalide.
  </Accordion>

  <Accordion title="POST /auth/logout">
    Invalide la session actuelle en détruisant le cookie de session.

    **Réponses :**
    - `200 OK` : Déconnexion réussie.
  </Accordion>
</Accordions>

### 👤 Utilisateurs (`/users`)

<Accordions>
  <Accordion title="GET /users/me">
    Récupère les informations détaillées de l'utilisateur connecté. Requiert l'authentification.

    **Réponses :**
    - `200 OK` : Retourne l'objet utilisateur complet (incluant données privées).
    - `401 Unauthorized` : Session invalide.
  </Accordion>

  <Accordion title="GET /users/public/:username">
    Récupère le profil public d'un utilisateur par son nom d'utilisateur. Mise en cache pendant 1 minute.

    **Réponses :**
    - `200 OK` : Profil public (id, username, displayName, bio, avatarUrl, createdAt).
    - `404 Not Found` : Utilisateur non trouvé.
  </Accordion>

  <Accordion title="GET /users/me/export">
    Extrait l'intégralité des données de l'utilisateur au format JSON (Conformité RGPD).
    Contient le profil, les contenus créés et les favoris.

    **Réponses :**
    - `200 OK` : Archive JSON des données.
    - `401 Unauthorized` : Non authentifié.
  </Accordion>

  <Accordion title="PATCH /users/me">
    Met à jour les informations du profil.

    **Corps de la requête :**
    - `displayName` (string, optional, max: 32)
    - `bio` (string, optional, max: 255)
    - `avatarUrl` (string, optional) : URL directe de l'avatar.

    **Réponses :**
    - `200 OK` : Profil mis à jour.
    - `400 Bad Request` : Validation échouée.
  </Accordion>

  <Accordion title="POST /users/me/avatar">
    Met à jour l'avatar de l'utilisateur via upload de fichier.

    **Type :** `multipart/form-data`
    **Champ :** `file` (Image: png, jpeg, webp)

    **Réponses :**
    - `201 Created` : Avatar téléchargé et mis à jour.
    - `400 Bad Request` : Fichier invalide ou trop volumineux.
  </Accordion>

  <Accordion title="PATCH /users/me/consent">
    Met à jour les consentements légaux de l'utilisateur (CGU/RGPD).

    **Corps de la requête :**
    - `termsVersion` (string, max: 16)
    - `privacyVersion` (string, max: 16)

    **Réponses :**
    - `200 OK` : Consentements enregistrés.
  </Accordion>

  <Accordion title="DELETE /users/me">
    Marque le compte pour suppression (Soft Delete). 
    <Callout type="warn">
      Les données sont définitivement purgées après un délai légal de 30 jours.
    </Callout>

    **Réponses :**
    - `200 OK` : Suppression planifiée.
  </Accordion>

  <Accordion title="POST /users/me/2fa/setup">
    Génère un secret et un QR Code pour la configuration de la 2FA.

    **Réponses :**
    - `201 Created` :
      ```json
      {
        "secret": "JBSWY3DPEHPK3PXP",
        "qrCodeDataUrl": "data:image/png;base64,..."
      }
      ```
  </Accordion>

  <Accordion title="POST /users/me/2fa/enable">
    Active la 2FA après vérification du jeton TOTP.

    **Corps de la requête :**
    - `token` (string) : Code TOTP généré par l'app.

    **Réponses :**
    - `200 OK` : 2FA activée.
    - `400 Bad Request` : Token invalide ou 2FA non initiée.
  </Accordion>

  <Accordion title="POST /users/me/2fa/disable">
    Désactive la 2FA en utilisant un jeton TOTP valide.

    **Corps de la requête :**
    - `token` (string) : Code TOTP.

    **Réponses :**
    - `200 OK` : 2FA désactivée.
  </Accordion>

  <Accordion title="GET /users/admin">
    Liste tous les utilisateurs. **Réservé aux administrateurs.**

    **Query Params :**
    - `limit` (number) : Défaut 10.
    - `offset` (number) : Défaut 0.

    **Réponses :**
    - `200 OK` : Liste paginée des utilisateurs.
    - `403 Forbidden` : Droits insuffisants.
  </Accordion>

  <Accordion title="DELETE /users/:uuid">
    Supprime définitivement un utilisateur par son UUID. **Réservé aux administrateurs.**

    **Réponses :**
    - `200 OK` : Utilisateur supprimé.
  </Accordion>
</Accordions>

### 🖼️ Contenus (`/contents`)

<Accordions>
  <Accordion title="GET /contents/explore">
    Recherche et filtre les contenus. Cet endpoint est mis en cache pendant 1 minute.
    
    **Query Params :**
    - `limit` (number) : Défaut 10.
    - `offset` (number) : Défaut 0.
    - `sort` : `trend` | `recent`
    - `tag` (string) : Filtrer par tag (nom).
    - `category` (slug ou uuid) : Filtrer par catégorie.
    - `author` (username) : Filtrer par auteur.
    - `query` (string) : Recherche textuelle dans le titre.
    - `favoritesOnly` (boolean) : Ne montrer que les favoris de l'utilisateur (nécessite auth).
    - `userId` (uuid) : Filtrer par ID utilisateur.

    **Réponses :**
    - `200 OK` : Liste paginée des contenus.
  </Accordion>

  <Accordion title="GET /contents/trends">
    Récupère les contenus les plus populaires du moment. Cache de 5 minutes.

    **Query Params :** `limit`, `offset`.

    **Réponses :**
    - `200 OK` : Liste des tendances.
  </Accordion>

  <Accordion title="GET /contents/recent">
    Récupère les contenus les plus récents. Cache de 1 minute.

    **Query Params :** `limit`, `offset`.

    **Réponses :**
    - `200 OK` : Liste des contenus récents.
  </Accordion>

  <Accordion title="GET /contents/:idOrSlug">
    Récupère un contenu par son ID ou son Slug. Cache de 1 heure.
    
    **Détection de Bots (SEO) :**
    Si l'User-Agent correspond à un robot d'indexation (Googlebot, Twitterbot, etc.), l'API retourne un rendu HTML minimal contenant les méta-tags **OpenGraph** et **Twitter Cards**.

    **Réponses :**
    - `200 OK` : Objet Contenu ou Rendu HTML (Bots).
    - `404 Not Found` : Contenu inexistant.
  </Accordion>

  <Accordion title="POST /contents">
    Crée une entrée de contenu à partir d'une ressource déjà uploadée ou externe.

    **Corps de la requête :**
    - `type` : `meme` | `gif`
    - `title` (string, max: 255)
    - `storageKey` (string, max: 512) : Clé du fichier sur S3.
    - `mimeType` (string, max: 128)
    - `fileSize` (number)
    - `categoryId` (uuid, optional)
    - `tags` (string[], optional)

    **Réponses :**
    - `201 Created` : Contenu référencé.
    - `401 Unauthorized` : Non authentifié.
  </Accordion>

  <Accordion title="POST /contents/upload">
    Upload un fichier et crée le contenu associé en une seule étape.

    **Type :** `multipart/form-data`
    **Champs :**
    - `file` (binary) : png, jpeg, webp, webm, gif.
    - `type` : `meme` | `gif`
    - `title` (string)
    - `categoryId` (uuid, optional)
    - `tags` (string[], optional)

    **Réponses :**
    - `201 Created` : Upload réussi et contenu créé.
    - `400 Bad Request` : Fichier non supporté ou données invalides.
  </Accordion>

  <Accordion title="POST /contents/upload-url">
    Génère une URL présignée pour un upload direct vers S3.

    **Query Param :**
    - `fileName` (string) : Nom du fichier avec extension.

    **Réponses :**
    - `201 Created` : Retourne l'URL présignée et les champs requis.
  </Accordion>

  <Accordion title="POST /contents/:id/view">
    Incrémente le compteur de vues d'un contenu.

    **Réponses :**
    - `201 Created` : Compteur incrémenté.
  </Accordion>

  <Accordion title="POST /contents/:id/use">
    Incrémente le compteur d'utilisation (clic sur "Utiliser").

    **Réponses :**
    - `201 Created` : Compteur incrémenté.
  </Accordion>

  <Accordion title="DELETE /contents/:id">
    Supprime un contenu (Soft Delete). Doit être l'auteur.

    **Réponses :**
    - `200 OK` : Contenu supprimé.
    - `403 Forbidden` : Tentative de supprimer le contenu d'autrui.
  </Accordion>

  <Accordion title="DELETE /contents/:id/admin">
    Supprime définitivement un contenu. **Réservé aux administrateurs.**

    **Réponses :**
    - `200 OK` : Contenu supprimé définitivement.
  </Accordion>
</Accordions>

### 📂 Catégories (`/categories`)

<Accordions>
  <Accordion title="GET /categories">
    Liste toutes les catégories de mèmes disponibles. Cache de 1 heure.

    **Réponses :**
    - `200 OK` : Liste d'objets catégorie.
  </Accordion>

  <Accordion title="GET /categories/:id">
    Récupère les détails d'une catégorie spécifique.

    **Réponses :**
    - `200 OK` : Objet catégorie.
    - `404 Not Found` : Catégorie non trouvée.
  </Accordion>

  <Accordion title="POST /categories">
    Crée une nouvelle catégorie. **Admin uniquement.**

    **Corps de la requête :**
    - `name` (string, max: 64)
    - `description` (string, optional, max: 255)
    - `iconUrl` (string, optional, max: 512)

    **Réponses :**
    - `201 Created` : Catégorie créée.
  </Accordion>

  <Accordion title="PATCH /categories/:id">
    Met à jour une catégorie existante. **Admin uniquement.**

    **Corps de la requête :** (Tous optionnels) `name`, `description`, `iconUrl`.

    **Réponses :**
    - `200 OK` : Catégorie mise à jour.
  </Accordion>

  <Accordion title="DELETE /categories/:id">
    Supprime une catégorie. **Admin uniquement.**

    **Réponses :**
    - `200 OK` : Catégorie supprimée.
  </Accordion>
</Accordions>

### ⭐ Favoris (`/favorites`)

<Accordions>
  <Accordion title="GET /favorites">
    Liste les favoris de l'utilisateur connecté.

    **Query Params :**
    - `limit` (number) : Défaut 10.
    - `offset` (number) : Défaut 0.

    **Réponses :**
    - `200 OK` : Liste paginée des favoris.
    - `401 Unauthorized` : Non authentifié.
  </Accordion>

  <Accordion title="POST /favorites/:contentId">
    Ajoute un contenu aux favoris de l'utilisateur.

    **Réponses :**
    - `201 Created` : Favori ajouté.
  </Accordion>

  <Accordion title="DELETE /favorites/:contentId">
    Retire un contenu des favoris de l'utilisateur.

    **Réponses :**
    - `200 OK` : Favori supprimé.
  </Accordion>
</Accordions>

### 🚩 Signalements (`/reports`)

<Accordions>
  <Accordion title="POST /reports">
    Signale un contenu ou un tag pour modération.

    **Corps de la requête :**
    - `contentId` (uuid, optional) : ID du contenu à signaler.
    - `tagId` (uuid, optional) : ID du tag à signaler.
    - `reason` : `inappropriate` | `spam` | `copyright` | `other`
    - `description` (string, optional, max: 1000)

    **Réponses :**
    - `201 Created` : Signalement enregistré.
  </Accordion>

  <Accordion title="GET /reports">
    Liste les signalements. **Réservé aux administrateurs et modérateurs.**

    **Query Params :**
    - `limit` (number) : Défaut 10.
    - `offset` (number) : Défaut 0.

    **Réponses :**
    - `200 OK` : Liste des signalements.
  </Accordion>

  <Accordion title="PATCH /reports/:id/status">
    Met à jour le statut d'un signalement. **Réservé aux administrateurs et modérateurs.**

    **Corps de la requête :**
    - `status` : `pending` | `reviewed` | `resolved` | `dismissed`

    **Réponses :**
    - `200 OK` : Statut mis à jour.
  </Accordion>
</Accordions>

### 🔑 Clés API (`/api-keys`)

<Accordions>
  <Accordion title="POST /api-keys">
    Génère une nouvelle clé API pour l'utilisateur.

    **Corps de la requête :**
    - `name` (string, max: 128) : Nom descriptif de la clé.
    - `expiresAt` (date-string, optional) : Date d'expiration.

    **Réponses :**
    - `201 Created` : Clé générée. Retourne le token (à conserver précieusement, ne sera plus affiché).
  </Accordion>

  <Accordion title="GET /api-keys">
    Liste toutes les clés API actives de l'utilisateur.

    **Réponses :**
    - `200 OK` : Liste des métadonnées des clés (nom, date de création, expiration).
  </Accordion>

  <Accordion title="DELETE /api-keys/:id">
    Révoque une clé API spécifique.

    **Réponses :**
    - `200 OK` : Clé révoquée.
  </Accordion>
</Accordions>

### 🏷️ Tags (`/tags`)

<Accordions>
  <Accordion title="GET /tags">
    Liste les tags populaires ou recherchés. Cache de 5 minutes.

    **Query Params :**
    - `limit` (number) : Défaut 10.
    - `offset` (number) : Défaut 0.
    - `query` (string, optional) : Recherche par nom.
    - `sort` : `popular` | `recent`

    **Réponses :**
    - `200 OK` : Liste paginée des tags.
  </Accordion>
</Accordions>

### 🛠️ Système (`/health`)

<Accordions>
  <Accordion title="GET /health">
    Vérifie l'état de santé de l'API et de ses dépendances (DB, Redis).

    **Réponses :**
    - `200 OK` : Système opérationnel.
      ```json
      {
        "status": "ok",
        "timestamp": "2024-01-21T10:00:00.000Z",
        "database": "connected",
        "redis": "connected"
      }
      ```
    - `503 Service Unavailable` : Problème sur l'un des composants.
  </Accordion>
</Accordions>

### 📁 Médias (`/media`)

<Accordions>
  <Accordion title="GET /media">
    Sert un fichier média stocké sur S3 avec une gestion optimisée du cache.

    **Query Params :**
    - `path` (string) : Chemin relatif du fichier sur le bucket.

    **Réponses :**
    - `200 OK` : Flux binaire du fichier. Headers `Content-Type` et `Cache-Control` inclus.
    - `404 Not Found` : Fichier introuvable.
  </Accordion>
</Accordions>

### 📊 Administration (`/admin`)

<Accordions>
  <Accordion title="GET /admin/stats">
    Récupère les statistiques globales d'utilisation de la plateforme (**Admin uniquement**).
  </Accordion>
</Accordions>
