openapi: 3.0.3
info:
  title: 'JaJa Project API Documentación Oficial'
  description: 'JaJa Project - La mejor comunidad para entretenimiento y compartir el humor'
  version: 1.0.0
servers:
  -
    url: 'https://jaja.raupulus.dev'
tags:
  -
    name: '🔐 Autenticación'
    description: ''
  -
    name: '🏷️ Categorías, Grupos y Tipos'
    description: ''
  -
    name: '📚 Contenidos'
    description: ''
  -
    name: '💡 Sugerencias'
    description: ''
  -
    name: '🚨 Reportes'
    description: ''
components:
  securitySchemes:
    default:
      type: http
      scheme: bearer
      description: 'Para obtener tu token logueate con tu cuenta de usuario y lo recibirás en la respuesta. También puedes acceder al panel para <b>generar el API TOKEN desde tu perfil</b>.'
security:
  -
    default: []
paths:
  /api/v1/auth/login:
    post:
      summary: Login
      operationId: login
      description: "Limitado a 3 intentos por minuto\n\nLo usamos para obtener token de acceso api y de sesión (para SPA por ejemplo)\n\nEl Token Bearer devuelto lo usaremos en los headers para las peticiones que requieran autenticación:\n\nBearer 5|dpsZX6OKLdrx1wYDfJqyMjg3kdAGdrmzDU4gMkJ1be4af09b"
      parameters: []
      responses:
        200:
          description: ''
          content:
            application/json:
              schema:
                type: object
                example:
                  success: true
                  data:
                    token: 5|dpsZX6OKLdrx1wYDfJqyMjg3kdAGdrmzDU4gMkJ1be4af09b
                    user:
                      name: 'Juan Pérez'
                      nick: juanito
                      urlImage: 'https://ejemplo.com/storage/user-images/avatar.webp'
                      email: juan@ejemplo.com
                      email_verified_at: '2024-01-15T10:30:00.000000Z'
                  message: 'Login exitoso'
                properties:
                  success:
                    type: boolean
                    example: true
                    description: 'Indica si la operación fue exitosa'
                    enum: []
                  data:
                    type: object
                    properties:
                      token:
                        type: string
                        example: 5|dpsZX6OKLdrx1wYDfJqyMjg3kdAGdrmzDU4gMkJ1be4af09b
                        description: 'Token Bearer para autenticación en futuras peticiones'
                        enum: []
                      user:
                        type: object
                        properties:
                          name:
                            type: string
                            example: 'Juan Pérez'
                            description: 'Nombre completo del usuario'
                            enum: []
                          nick:
                            type: string
                            example: juanito
                            description: 'Apodo único del usuario'
                            enum: []
                          urlImage:
                            type: string
                            example: 'https://ejemplo.com/storage/user-images/avatar.webp'
                            description: 'URL completa de la imagen de perfil'
                            enum: []
                          email:
                            type: string
                            example: juan@ejemplo.com
                            description: 'Email del usuario (incluido al ser el propio usuario)'
                            enum: []
                          email_verified_at:
                            type: string
                            example: '2024-01-15T10:30:00.000000Z'
                            description: 'Fecha de verificación del email ISO 8601'
                            enum: []
                        description: 'Información del usuario autenticado'
                    description: 'Datos de respuesta del login (solo si es exitoso)'
                  message:
                    type: string
                    example: 'Login exitoso'
                    description: 'Mensaje descriptivo de la operación'
                    enum: []
        401:
          description: ''
          content:
            application/json:
              schema:
                type: object
                example:
                  success: false
                  message: 'Las credenciales proporcionadas son incorrectas.'
                properties:
                  success:
                    type: boolean
                    example: false
                    description: 'Indica si la operación fue exitosa'
                    enum: []
                  message:
                    type: string
                    example: 'Las credenciales proporcionadas son incorrectas.'
                    description: 'Mensaje descriptivo de la operación'
                    enum: []
      tags:
        - '🔐 Autenticación'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                email:
                  type: string
                  description: 'Email del usuario. El formato del value no es válido.'
                  example: user@example.com
                  nullable: false
                password:
                  type: string
                  description: 'Contraseña del usuario. El campo value debe tener al menos 8 caracteres. El campo value debe ser menor que 100 caracteres.'
                  example: mipasswordsupersegura123123123
                  nullable: false
                device_name:
                  type: string
                  description: 'Nombre del dispositivo para generar el token y asociarlo a este. El campo value debe ser menor que 100 caracteres.'
                  example: 'Mi iPhone 13 Pro'
                  nullable: false
              required:
                - email
                - password
                - device_name
      security: []
  /api/v1/auth/logout:
    post:
      summary: Logout
      operationId: logout
      description: 'Cierra la sesión de un usuario e invalida el token de acceso utilizado en ese momento'
      parameters: []
      responses:
        200:
          description: ''
          content:
            application/json:
              schema:
                type: object
                example:
                  success: true
                  data: null
                  message: 'Sesión cerrada exitosamente'
                properties:
                  success:
                    type: boolean
                    example: true
                    description: 'Indica si la operación fue exitosa'
                    enum: []
                  data:
                    type: string
                    example: null
                    description: 'null No se devuelven datos adicionales'
                    enum: []
                  message:
                    type: string
                    example: 'Sesión cerrada exitosamente'
                    description: 'Mensaje descriptivo de la operación'
                    enum: []
      tags:
        - '🔐 Autenticación'
  /api/v1/auth/user:
    get:
      summary: 'Información de usuario'
      operationId: informacinDeUsuario
      description: 'Devuelve la información del usuario actualmente logueado en la plataforma'
      parameters: []
      responses:
        200:
          description: ''
          content:
            application/json:
              schema:
                type: object
                example:
                  success: true
                  data:
                    name: 'Juan Pérez'
                    nick: juanito
                    urlImage: 'https://ejemplo.com/storage/user-images/avatar.webp'
                    email: juan@ejemplo.com
                    email_verified_at: '2024-01-15T10:30:00.000000Z'
                  message: 'Información del usuario obtenida'
                properties:
                  success:
                    type: boolean
                    example: true
                    description: 'Indica si la operación fue exitosa'
                    enum: []
                  data:
                    type: object
                    properties:
                      name:
                        type: string
                        example: 'Juan Pérez'
                        description: 'Nombre completo del usuario'
                        enum: []
                      nick:
                        type: string
                        example: juanito
                        description: 'Apodo único del usuario (máximo 25 caracteres)'
                        enum: []
                      urlImage:
                        type: string
                        example: 'https://ejemplo.com/storage/user-images/avatar.webp'
                        description: 'URL completa de la imagen de perfil del usuario'
                        enum: []
                      email:
                        type: string
                        example: juan@ejemplo.com
                        description: 'Email del usuario (solo si es el propio usuario autenticado)'
                        enum: []
                      email_verified_at:
                        type: string
                        example: '2024-01-15T10:30:00.000000Z'
                        description: 'Fecha de verificación del email en formato ISO 8601 (solo si es el propio usuario autenticado)'
                        enum: []
                    description: 'Datos del usuario'
                  message:
                    type: string
                    example: 'Información del usuario obtenida'
                    description: 'Mensaje descriptivo de la operación'
                    enum: []
      tags:
        - '🔐 Autenticación'
  /api/v1/types:
    get:
      summary: 'Tipos de Contenido'
      operationId: tiposDeContenido
      description: "Devuelve la lista de tipos de contenido que existen.\n\nÚtil para utilizar el slug del tipo que necesites y filtrar en otros endpoints."
      parameters: []
      responses:
        200:
          description: ''
          content:
            application/json:
              schema:
                type: object
                example:
                  success: true
                  data:
                    -
                      name: Quiz
                      slug: quiz
                      description: 'Preguntas tipo quiz'
                      urlImage: null
                    -
                      name: Chistes
                      slug: chistes
                      description: 'Chistes, bromas y situaciones de humor'
                      urlImage: null
                    -
                      name: Adivinanzas
                      slug: adivinanzas
                      description: 'Adivinanzas para reflexionarAdivinanzas para reflexionarAdivinanzas para reflexionarAdivinanzas para reflexionarAdivinanzas para reflexionarAdivinanzas para reflexionarAdivinanzas para reflexionar'
                      urlImage: 'http://jaja.raupulus.dev/storage/general/1751920088_oHVOUYtCWj.webp'
                  message: 'Se obtuvieron 3 tipos'
                  meta:
                    total_items: 3
                properties:
                  success:
                    type: boolean
                    example: true
                    description: 'Indica si la operación fue exitosa'
                    enum: []
                  data:
                    type: array
                    example:
                      -
                        name: Quiz
                        slug: quiz
                        description: 'Preguntas tipo quiz'
                        urlImage: null
                      -
                        name: Chistes
                        slug: chistes
                        description: 'Chistes, bromas y situaciones de humor'
                        urlImage: null
                      -
                        name: Adivinanzas
                        slug: adivinanzas
                        description: 'Adivinanzas para reflexionarAdivinanzas para reflexionarAdivinanzas para reflexionarAdivinanzas para reflexionarAdivinanzas para reflexionarAdivinanzas para reflexionarAdivinanzas para reflexionar'
                        urlImage: 'http://jaja.raupulus.dev/storage/general/1751920088_oHVOUYtCWj.webp'
                    description: 'Lista de tipos de contenido disponibles'
                    enum: []
                    items:
                      type: object
                      properties:
                        name:
                          type: string
                          example: Quiz
                        slug:
                          type: string
                          example: quiz
                        description:
                          type: string
                          example: 'Preguntas tipo quiz'
                        urlImage:
                          type: string
                          example: null
                  message:
                    type: string
                    example: 'Se obtuvieron 3 tipos'
                    description: 'Mensaje descriptivo de la operación'
                    enum: []
                  meta:
                    type: object
                    properties:
                      total_items:
                        type: integer
                        example: 3
                        description: 'Número total de tipos disponibles'
                        enum: []
                    description: 'Metadatos adicionales de la respuesta'
        404:
          description: ''
          content:
            application/json:
              schema:
                type: object
                example:
                  success: false
                  message: 'No se encontraron tipos de contenido'
                properties:
                  success:
                    type: boolean
                    example: false
                    description: 'Indica si la operación fue exitosa'
                    enum: []
                  message:
                    type: string
                    example: 'No se encontraron tipos de contenido'
                    description: 'Mensaje descriptivo de la operación'
                    enum: []
        500:
          description: ''
          content:
            application/json:
              schema:
                type: object
                example:
                  success: false
                  message: 'Error al obtener la lista de tipos'
                properties:
                  success:
                    type: boolean
                    example: false
                    description: 'Indica si la operación fue exitosa'
                    enum: []
                  message:
                    type: string
                    example: 'Error al obtener la lista de tipos'
                    description: 'Mensaje descriptivo de la operación'
                    enum: []
      tags:
        - '🏷️ Categorías, Grupos y Tipos'
  /api/v1/groups:
    get:
      summary: 'Grupos de Contenidos'
      operationId: gruposDeContenidos
      description: 'Devuelve la lista de grupos de contenido que existen paginados.'
      parameters:
        -
          in: query
          name: page
          description: 'Número de página a obtener. El campo value debe tener al menos 1.'
          example: 1
          required: false
          schema:
            type: integer
            description: 'Número de página a obtener. El campo value debe tener al menos 1.'
            example: 1
            nullable: false
        -
          in: query
          name: limit
          description: 'Cantidad de elementos por página (máximo 50). El campo value debe tener al menos 1. El campo value no debe de ser mayor a 50.'
          example: 2
          required: false
          schema:
            type: integer
            description: 'Cantidad de elementos por página (máximo 50). El campo value debe tener al menos 1. El campo value no debe de ser mayor a 50.'
            example: 2
            nullable: false
      responses:
        200:
          description: ''
          content:
            application/json:
              schema:
                type: object
                example:
                  success: true
                  data:
                    -
                      title: 'Preguntas en General'
                      slug: quiz-general
                      urlImage: null
                    -
                      title: 'Preguntas Programación'
                      slug: quiz-devs
                      urlImage: null
                  message: 'Se obtuvieron 2 grupos de contenido'
                  meta:
                    pagination:
                      current_page: 1
                      per_page: 2
                      total: 12
                      last_page: 6
                      from: 1
                      to: 2
                      has_more_pages: true
                      has_previous_page: false
                      next_page_url: 'http://localhost:8000/api/v1/groups?groups_index=2'
                      prev_page_url: null
                properties:
                  success:
                    type: boolean
                    example: true
                    description: 'Indica si la operación fue exitosa'
                    enum: []
                  data:
                    type: array
                    example:
                      -
                        title: 'Preguntas en General'
                        slug: quiz-general
                        urlImage: null
                      -
                        title: 'Preguntas Programación'
                        slug: quiz-devs
                        urlImage: null
                    description: 'Lista de grupos de contenido paginados'
                    enum: []
                    items:
                      type: object
                      properties:
                        title:
                          type: string
                          example: 'Preguntas en General'
                        slug:
                          type: string
                          example: quiz-general
                        urlImage:
                          type: string
                          example: null
                  message:
                    type: string
                    example: 'Se obtuvieron 2 grupos de contenido'
                    description: 'Mensaje descriptivo de la operación'
                    enum: []
                  meta:
                    type: object
                    properties:
                      pagination:
                        type: object
                        properties:
                          current_page:
                            type: integer
                            example: 1
                          per_page:
                            type: integer
                            example: 2
                          total:
                            type: integer
                            example: 12
                          last_page:
                            type: integer
                            example: 6
                          from:
                            type: integer
                            example: 1
                          to:
                            type: integer
                            example: 2
                          has_more_pages:
                            type: boolean
                            example: true
                          has_previous_page:
                            type: boolean
                            example: false
                          next_page_url:
                            type: string
                            example: 'http://localhost:8000/api/v1/groups?groups_index=2'
                          prev_page_url:
                            type: string
                            example: null
        404:
          description: ''
          content:
            application/json:
              schema:
                oneOf:
                  -
                    description: ''
                    type: object
                    example:
                      success: false
                      message: 'La página solicitada no existe. Última página disponible: 2'
                    properties:
                      success:
                        type: boolean
                        example: false
                        description: 'Indica si la operación fue exitosa'
                        enum: []
                      message:
                        type: string
                        example: 'La página solicitada no existe. Última página disponible: 2'
                        description: 'Mensaje descriptivo de la operación'
                        enum: []
                  -
                    description: ''
                    type: object
                    example:
                      success: false
                      message: 'No se encontraron grupos de contenido'
                    properties:
                      success:
                        type: boolean
                        example: false
                        description: 'Indica si la operación fue exitosa'
                        enum: []
                      message:
                        type: string
                        example: 'No se encontraron grupos de contenido'
                        description: 'Mensaje descriptivo de la operación'
                        enum: []
        500:
          description: ''
          content:
            application/json:
              schema:
                type: object
                example:
                  success: false
                  message: 'Error al obtener la lista de grupos'
                properties:
                  success:
                    type: boolean
                    example: false
                    description: 'Indica si la operación fue exitosa'
                    enum: []
                  message:
                    type: string
                    example: 'Error al obtener la lista de grupos'
                    description: 'Mensaje descriptivo de la operación'
                    enum: []
      tags:
        - '🏷️ Categorías, Grupos y Tipos'
  /api/v1/categories:
    get:
      summary: Categorías
      operationId: categoras
      description: 'Devuelve la lista de categorías disponibles paginadas.'
      parameters:
        -
          in: query
          name: page
          description: 'Número de página a obtener. El campo value debe tener al menos 1.'
          example: 1
          required: false
          schema:
            type: integer
            description: 'Número de página a obtener. El campo value debe tener al menos 1.'
            example: 1
            nullable: false
        -
          in: query
          name: limit
          description: 'Cantidad de elementos por página (máximo 50). El campo value debe tener al menos 1. El campo value no debe de ser mayor a 50.'
          example: 2
          required: false
          schema:
            type: integer
            description: 'Cantidad de elementos por página (máximo 50). El campo value debe tener al menos 1. El campo value no debe de ser mayor a 50.'
            example: 2
            nullable: false
      responses:
        200:
          description: ''
          content:
            application/json:
              schema:
                type: object
                example:
                  success: true
                  data:
                    -
                      title: iOS
                      slug: ios
                      description: 'Sistema operativo de Apple para dispositivos móviles'
                      urlImage: null
                    -
                      title: Vue.js
                      slug: vue-js
                      description: 'Framework progresivo para la interfaz de usuario'
                      urlImage: null
                  message: 'Se obtuvieron 2 categorías de 105, página 1.'
                  meta:
                    pagination:
                      current_page: 1
                      per_page: 2
                      total: 105
                      last_page: 53
                      from: 1
                      to: 2
                      has_more_pages: true
                      has_previous_page: false
                      next_page_url: 'http://localhost:8000/api/v1/categories?page=2'
                      prev_page_url: null
                properties:
                  success:
                    type: boolean
                    example: true
                    description: 'Indica si la operación fue exitosa'
                    enum: []
                  data:
                    type: array
                    example:
                      -
                        title: iOS
                        slug: ios
                        description: 'Sistema operativo de Apple para dispositivos móviles'
                        urlImage: null
                      -
                        title: Vue.js
                        slug: vue-js
                        description: 'Framework progresivo para la interfaz de usuario'
                        urlImage: null
                    description: 'Lista de categorías paginadas'
                    enum: []
                    items:
                      type: object
                      properties:
                        title:
                          type: string
                          example: iOS
                        slug:
                          type: string
                          example: ios
                        description:
                          type: string
                          example: 'Sistema operativo de Apple para dispositivos móviles'
                        urlImage:
                          type: string
                          example: null
                  message:
                    type: string
                    example: 'Se obtuvieron 2 categorías de 105, página 1.'
                    description: 'Mensaje descriptivo de la operación'
                    enum: []
                  meta:
                    type: object
                    properties:
                      pagination:
                        type: object
                        properties:
                          current_page:
                            type: integer
                            example: 1
                          per_page:
                            type: integer
                            example: 2
                          total:
                            type: integer
                            example: 105
                          last_page:
                            type: integer
                            example: 53
                          from:
                            type: integer
                            example: 1
                          to:
                            type: integer
                            example: 2
                          has_more_pages:
                            type: boolean
                            example: true
                          has_previous_page:
                            type: boolean
                            example: false
                          next_page_url:
                            type: string
                            example: 'http://localhost:8000/api/v1/categories?page=2'
                          prev_page_url:
                            type: string
                            example: null
        404:
          description: ''
          content:
            application/json:
              schema:
                oneOf:
                  -
                    description: ''
                    type: object
                    example:
                      success: false
                      message: 'No se han encontrado categorías'
                    properties:
                      success:
                        type: boolean
                        example: false
                        description: 'Indica si la operación fue exitosa'
                        enum: []
                      message:
                        type: string
                        example: 'No se han encontrado categorías'
                        description: 'Mensaje descriptivo de la operación'
                        enum: []
                  -
                    description: ''
                    type: object
                    example:
                      success: false
                      message: 'La página solicitada no existe. Última página disponible: 5'
                    properties:
                      success:
                        type: boolean
                        example: false
                        description: 'Indica si la operación fue exitosa'
                        enum: []
                      message:
                        type: string
                        example: 'La página solicitada no existe. Última página disponible: 5'
                        description: 'Mensaje descriptivo de la operación'
                        enum: []
        500:
          description: ''
          content:
            application/json:
              schema:
                type: object
                example:
                  success: false
                  message: 'Error al obtener la lista de categorías'
                properties:
                  success:
                    type: boolean
                    example: false
                    description: 'Indica si la operación fue exitosa'
                    enum: []
                  message:
                    type: string
                    example: 'Error al obtener la lista de categorías'
                    description: 'Mensaje descriptivo de la operación'
                    enum: []
      tags:
        - '🏷️ Categorías, Grupos y Tipos'
  /api/v1/random:
    get:
      summary: 'Contenido Aleatorio'
      operationId: contenidoAleatorio
      description: "Devuelve un contenido aleatorio de entre todos los existentes en la plataforma sin filtro alguno.\n\nEste endpoint al ser público está limitado a máximo 5 elementos por petición y a 10 peticiones por minuto."
      parameters:
        -
          in: query
          name: limit
          description: 'Cantidad de elementos por página (máximo 5). El campo value debe tener al menos 1. El campo value no debe de ser mayor a 5.'
          example: 1
          required: false
          schema:
            type: integer
            description: 'Cantidad de elementos por página (máximo 5). El campo value debe tener al menos 1. El campo value no debe de ser mayor a 5.'
            example: 1
            nullable: false
      responses:
        200:
          description: ''
          content:
            application/json:
              schema:
                type: object
                example:
                  success: true
                  data:
                    -
                      id: 237
                      title: 'Patrulla con sirenas'
                      content: 'Por qué en Lepe los coches patrulla llevan encima una bañera? Para llevar las sirenas!'
                      urlImage: null
                      uploader: '@raupulus'
                      options: []
                  message: 'Se obtuvo 1 contenido aleatorio'
                  meta:
                    total_items: 268
                    limit: 1
                properties:
                  success:
                    type: boolean
                    example: true
                    description: 'Indica si la operación fue exitosa'
                    enum: []
                  data:
                    type: array
                    example:
                      -
                        id: 237
                        title: 'Patrulla con sirenas'
                        content: 'Por qué en Lepe los coches patrulla llevan encima una bañera? Para llevar las sirenas!'
                        urlImage: null
                        uploader: '@raupulus'
                        options: []
                    description: 'Colección de contenidos aleatorios'
                    enum: []
                    items:
                      type: object
                      properties:
                        id:
                          type: integer
                          example: 237
                        title:
                          type: string
                          example: 'Patrulla con sirenas'
                        content:
                          type: string
                          example: 'Por qué en Lepe los coches patrulla llevan encima una bañera? Para llevar las sirenas!'
                        urlImage:
                          type: string
                          example: null
                        uploader:
                          type: string
                          example: '@raupulus'
                        options:
                          type: array
                          example: []
                  message:
                    type: string
                    example: 'Se obtuvo 1 contenido aleatorio'
                    description: 'Mensaje descriptivo de la operación'
                    enum: []
                  meta:
                    type: object
                    properties:
                      total_items:
                        type: integer
                        example: 268
                        description: 'Número total de contenidos disponibles'
                        enum: []
                      limit:
                        type: integer
                        example: 1
                        description: 'Límite aplicado en esta consulta'
                        enum: []
                    description: 'Metadatos adicionales de la respuesta'
        404:
          description: ''
          content:
            application/json:
              schema:
                type: object
                example:
                  success: false
                  message: 'No se encontraron contenidos'
                properties:
                  success:
                    type: boolean
                    example: false
                    description: 'Indica si la operación fue exitosa'
                    enum: []
                  message:
                    type: string
                    example: 'No se encontraron contenidos'
                    description: 'Mensaje descriptivo de la operación'
                    enum: []
        500:
          description: ''
          content:
            application/json:
              schema:
                type: object
                example:
                  success: false
                  message: 'Error al obtener chistes aleatorios'
                properties:
                  success:
                    type: boolean
                    example: false
                    description: 'Indica si la operación fue exitosa'
                    enum: []
                  message:
                    type: string
                    example: 'Error al obtener chistes aleatorios'
                    description: 'Mensaje descriptivo de la operación'
                    enum: []
      tags:
        - '📚 Contenidos'
      security: []
  '/api/v1/random/{type_slug}':
    get:
      summary: 'Contenido Aleatorio'
      operationId: contenidoAleatorio
      description: "Devuelve un contenido aleatorio de entre todos los existentes en la plataforma filtrando por tipo\n[chistes|adivinanzas|quiz].\n\nEste endpoint al ser público está limitado a máximo 5 elementos por petición y a 10 peticiones por minuto."
      parameters:
        -
          in: query
          name: limit
          description: 'Cantidad de elementos por página (máximo 5). El campo value debe tener al menos 1. El campo value no debe de ser mayor a 5.'
          example: 1
          required: false
          schema:
            type: integer
            description: 'Cantidad de elementos por página (máximo 5). El campo value debe tener al menos 1. El campo value no debe de ser mayor a 5.'
            example: 1
            nullable: false
      responses:
        200:
          description: ''
          content:
            application/json:
              schema:
                type: object
                example:
                  success: true
                  data:
                    -
                      id: 188
                      title: 'Ketchup en la oreja'
                      content: 'Que hace uno de lepe con un sobre de ketchup en la oreja? Escuchar salsa'
                      urlImage: null
                      uploader: '@raupulus'
                      options: []
                  message: 'Se obtuvo 1 contenido aleatorio'
                  meta:
                    total_items: 265
                    limit: 1
                properties:
                  success:
                    type: boolean
                    example: true
                    description: 'Indica si la operación fue exitosa'
                    enum: []
                  data:
                    type: array
                    example:
                      -
                        id: 188
                        title: 'Ketchup en la oreja'
                        content: 'Que hace uno de lepe con un sobre de ketchup en la oreja? Escuchar salsa'
                        urlImage: null
                        uploader: '@raupulus'
                        options: []
                    description: 'Colección de contenidos aleatorios'
                    enum: []
                    items:
                      type: object
                      properties:
                        id:
                          type: integer
                          example: 188
                        title:
                          type: string
                          example: 'Ketchup en la oreja'
                        content:
                          type: string
                          example: 'Que hace uno de lepe con un sobre de ketchup en la oreja? Escuchar salsa'
                        urlImage:
                          type: string
                          example: null
                        uploader:
                          type: string
                          example: '@raupulus'
                        options:
                          type: array
                          example: []
                  message:
                    type: string
                    example: 'Se obtuvo 1 contenido aleatorio'
                    description: 'Mensaje descriptivo de la operación'
                    enum: []
                  meta:
                    type: object
                    properties:
                      total_items:
                        type: integer
                        example: 265
                        description: 'Número total de contenidos disponibles'
                        enum: []
                      limit:
                        type: integer
                        example: 1
                        description: 'Límite aplicado en esta consulta'
                        enum: []
                    description: 'Metadatos adicionales de la respuesta'
        404:
          description: ''
          content:
            application/json:
              schema:
                type: object
                example:
                  success: false
                  message: 'No se encontraron contenidos'
                properties:
                  success:
                    type: boolean
                    example: false
                    description: 'Indica si la operación fue exitosa'
                    enum: []
                  message:
                    type: string
                    example: 'No se encontraron contenidos'
                    description: 'Mensaje descriptivo de la operación'
                    enum: []
        500:
          description: ''
          content:
            application/json:
              schema:
                type: object
                example:
                  success: false
                  message: 'Error al obtener chistes aleatorios'
                properties:
                  success:
                    type: boolean
                    example: false
                    description: 'Indica si la operación fue exitosa'
                    enum: []
                  message:
                    type: string
                    example: 'Error al obtener chistes aleatorios'
                    description: 'Mensaje descriptivo de la operación'
                    enum: []
      tags:
        - '📚 Contenidos'
      security: []
    parameters:
      -
        in: path
        name: type_slug
        description: 'El slug del tipo de contenido [chistes|adivinanzas|quiz].'
        example: chistes
        required: true
        schema:
          type: string
  '/api/v1/type/{type_slug}/content/random':
    get:
      summary: 'Contenido en base a un tipo'
      operationId: contenidoEnBaseAUnTipo
      description: 'Devuelve un contenido aleatorio de un tipo concreto recibido.'
      parameters:
        -
          in: query
          name: limit
          description: 'Cantidad de elementos por página (máximo 5). El campo value debe tener al menos 1. El campo value no debe de ser mayor a 5.'
          example: 1
          required: false
          schema:
            type: integer
            description: 'Cantidad de elementos por página (máximo 5). El campo value debe tener al menos 1. El campo value no debe de ser mayor a 5.'
            example: 1
            nullable: false
      responses:
        200:
          description: ''
          content:
            application/json:
              schema:
                type: object
                example:
                  success: true
                  data:
                    -
                      id: 204
                      title: 'Llamada telefónica'
                      content: 'Llama un lepero por teléfono y le contestan: - ¿Si.....dígame? - Doctor, doctor, mi mujer está a punto de dar a luz. - ¿Es su primer hijo? - No, soy su marido.'
                      urlImage: null
                      uploader: '@raupulus'
                      options: []
                  message: 'Se devuelve 1 contenido aleatorio para el tipo Chistes de 265 contenidos totales para este tipo.'
                  meta:
                    type: Chistes
                    type_slug: chistes
                    total_items: 265
                properties:
                  success:
                    type: boolean
                    example: true
                    description: 'Indica si la operación fue exitosa'
                    enum: []
                  data:
                    type: array
                    example:
                      -
                        id: 204
                        title: 'Llamada telefónica'
                        content: 'Llama un lepero por teléfono y le contestan: - ¿Si.....dígame? - Doctor, doctor, mi mujer está a punto de dar a luz. - ¿Es su primer hijo? - No, soy su marido.'
                        urlImage: null
                        uploader: '@raupulus'
                        options: []
                    description: 'Lista con el contenido aleatorio solicitado'
                    enum: []
                    items:
                      type: object
                      properties:
                        id:
                          type: integer
                          example: 204
                        title:
                          type: string
                          example: 'Llamada telefónica'
                        content:
                          type: string
                          example: 'Llama un lepero por teléfono y le contestan: - ¿Si.....dígame? - Doctor, doctor, mi mujer está a punto de dar a luz. - ¿Es su primer hijo? - No, soy su marido.'
                        urlImage:
                          type: string
                          example: null
                        uploader:
                          type: string
                          example: '@raupulus'
                        options:
                          type: array
                          example: []
                  message:
                    type: string
                    example: 'Se devuelve 1 contenido aleatorio para el tipo Chistes de 265 contenidos totales para este tipo.'
                    description: 'Mensaje descriptivo de la operación'
                    enum: []
                  meta:
                    type: object
                    properties:
                      type:
                        type: string
                        example: Chistes
                        description: 'Nombre del tipo de contenido'
                        enum: []
                      type_slug:
                        type: string
                        example: chistes
                        description: 'Slug del tipo'
                        enum: []
                      total_items:
                        type: integer
                        example: 265
                        description: 'Total de contenidos disponibles para este tipo'
                        enum: []
                    description: 'Metadatos adicionales de la respuesta'
        404:
          description: ''
          content:
            application/json:
              schema:
                type: object
                example:
                  success: false
                  message: 'No se encontraron contenidos para el tipo especificado'
                properties:
                  success:
                    type: boolean
                    example: false
                    description: 'Indica si la operación fue exitosa'
                    enum: []
                  message:
                    type: string
                    example: 'No se encontraron contenidos para el tipo especificado'
                    description: 'Mensaje descriptivo de la operación'
                    enum: []
        500:
          description: ''
          content:
            application/json:
              schema:
                type: object
                example:
                  success: false
                  message: 'Error al obtener contenidos del tipo especificado'
                properties:
                  success:
                    type: boolean
                    example: false
                    description: 'Indica si la operación fue exitosa'
                    enum: []
                  message:
                    type: string
                    example: 'Error al obtener contenidos del tipo especificado'
                    description: 'Mensaje descriptivo de la operación'
                    enum: []
      tags:
        - '📚 Contenidos'
    parameters:
      -
        in: path
        name: type_slug
        description: 'El slug del tipo de contenido [chistes|adivinanzas|quiz].'
        example: chistes
        required: true
        schema:
          type: string
  '/api/v1/type/{type_slug}/category/{categorySlug}/content/random':
    get:
      summary: 'Contenido en base a un tipo y Categoría'
      operationId: contenidoEnBaseAUnTipoYCategora
      description: 'Devuelve un contenido aleatorio que pertenezca al tipo y categoría recibido.'
      parameters:
        -
          in: query
          name: limit
          description: 'Cantidad de elementos por página (máximo 5). El campo value debe tener al menos 1. El campo value no debe de ser mayor a 5.'
          example: 1
          required: false
          schema:
            type: integer
            description: 'Cantidad de elementos por página (máximo 5). El campo value debe tener al menos 1. El campo value no debe de ser mayor a 5.'
            example: 1
            nullable: false
      responses:
        200:
          description: ''
          content:
            application/json:
              schema:
                type: object
                example:
                  success: true
                  data:
                    -
                      id: 93
                      title: 'JavaScript: el lenguaje universal de los aliens'
                      content: "¿Cuál es el lenguaje de programación favorito de los extraterrestres?\nJavaScript, porque es universal."
                      urlImage: null
                      uploader: '@raupulus'
                      options: []
                  message: 'Se devuelve 1 contenido aleatorio para el tipo Chistes y la categoría JavaScript de 2 contenidos totales.'
                  meta:
                    type: Chistes
                    type_slug: chistes
                    category: JavaScript
                    category_slug: javascript
                    total_items: 2
                properties:
                  success:
                    type: boolean
                    example: true
                    description: 'Indica si la operación fue exitosa'
                    enum: []
                  data:
                    type: array
                    example:
                      -
                        id: 93
                        title: 'JavaScript: el lenguaje universal de los aliens'
                        content: "¿Cuál es el lenguaje de programación favorito de los extraterrestres?\nJavaScript, porque es universal."
                        urlImage: null
                        uploader: '@raupulus'
                        options: []
                    description: 'Lista con el contenido aleatorio solicitado'
                    enum: []
                    items:
                      type: object
                      properties:
                        id:
                          type: integer
                          example: 93
                        title:
                          type: string
                          example: 'JavaScript: el lenguaje universal de los aliens'
                        content:
                          type: string
                          example: "¿Cuál es el lenguaje de programación favorito de los extraterrestres?\nJavaScript, porque es universal."
                        urlImage:
                          type: string
                          example: null
                        uploader:
                          type: string
                          example: '@raupulus'
                        options:
                          type: array
                          example: []
                  message:
                    type: string
                    example: 'Se devuelve 1 contenido aleatorio para el tipo Chistes y la categoría JavaScript de 2 contenidos totales.'
                    description: 'Mensaje descriptivo de la operación'
                    enum: []
                  meta:
                    type: object
                    properties:
                      type:
                        type: string
                        example: Chistes
                        description: 'Nombre del tipo de contenido'
                        enum: []
                      type_slug:
                        type: string
                        example: chistes
                        description: 'Slug del tipo'
                        enum: []
                      category:
                        type: string
                        example: JavaScript
                        description: 'Título de la categoría'
                        enum: []
                      category_slug:
                        type: string
                        example: javascript
                        description: 'Slug de la categoría'
                        enum: []
                      total_items:
                        type: integer
                        example: 2
                        description: 'Total de contenidos disponibles para este tipo y categoría'
                        enum: []
                    description: 'Metadatos adicionales de la respuesta'
        404:
          description: ''
          content:
            application/json:
              schema:
                oneOf:
                  -
                    description: ''
                    type: object
                    example:
                      success: false
                      message: 'Categoría no encontrada'
                    properties:
                      success:
                        type: boolean
                        example: false
                        description: 'Indica si la operación fue exitosa'
                        enum: []
                      message:
                        type: string
                        example: 'Categoría no encontrada'
                        description: 'Mensaje descriptivo de la operación'
                        enum: []
                  -
                    description: ''
                    type: object
                    example:
                      success: false
                      message: 'No se encontraron contenidos para el tipo y categoría especificados'
                    properties:
                      success:
                        type: boolean
                        example: false
                        description: 'Indica si la operación fue exitosa'
                        enum: []
                      message:
                        type: string
                        example: 'No se encontraron contenidos para el tipo y categoría especificados'
                        description: 'Mensaje descriptivo de la operación'
                        enum: []
        500:
          description: ''
          content:
            application/json:
              schema:
                type: object
                example:
                  success: false
                  message: 'Error al obtener contenidos del tipo especificado'
                properties:
                  success:
                    type: boolean
                    example: false
                    description: 'Indica si la operación fue exitosa'
                    enum: []
                  message:
                    type: string
                    example: 'Error al obtener contenidos del tipo especificado'
                    description: 'Mensaje descriptivo de la operación'
                    enum: []
      tags:
        - '📚 Contenidos'
    parameters:
      -
        in: path
        name: type_slug
        description: 'El slug del tipo de contenido [chistes|adivinanzas|quiz].'
        example: chistes
        required: true
        schema:
          type: string
      -
        in: path
        name: categorySlug
        description: 'El slug de la categoría.'
        example: javascript
        required: true
        schema:
          type: string
  '/api/v1/group/{group_slug}/content/random':
    get:
      summary: 'Contenido en base a un grupo'
      operationId: contenidoEnBaseAUnGrupo
      description: 'Contenido aleatorio que pertenecen al grupo recibido.'
      parameters:
        -
          in: query
          name: limit
          description: 'Cantidad de elementos por página (máximo 5). El campo value debe tener al menos 1. El campo value no debe de ser mayor a 5.'
          example: 1
          required: false
          schema:
            type: integer
            description: 'Cantidad de elementos por página (máximo 5). El campo value debe tener al menos 1. El campo value no debe de ser mayor a 5.'
            example: 1
            nullable: false
      responses:
        200:
          description: ''
          content:
            application/json:
              schema:
                type: object
                example:
                  success: true
                  data:
                    -
                      id: 121
                      title: 'El project manager en el laberinto: siempre con plan B'
                      content: "¿Por qué el project manager nunca se asusta en un laberinto?\nPorque siempre tiene un \"plan de salida\"."
                      urlImage: null
                      uploader: '@raupulus'
                      options: []
                  message: 'Se devuelve 1 contenido aleatorio para el grupo Chistes de Programación de 126 contenidos totales.'
                  meta:
                    group: 'Chistes de Programación'
                    group_slug: chistes-devs
                    total_items: 126
                properties:
                  success:
                    type: boolean
                    example: true
                    description: 'Indica si la operación fue exitosa'
                    enum: []
                  data:
                    type: array
                    example:
                      -
                        id: 121
                        title: 'El project manager en el laberinto: siempre con plan B'
                        content: "¿Por qué el project manager nunca se asusta en un laberinto?\nPorque siempre tiene un \"plan de salida\"."
                        urlImage: null
                        uploader: '@raupulus'
                        options: []
                    description: 'Lista con el contenido aleatorio solicitado'
                    enum: []
                    items:
                      type: object
                      properties:
                        id:
                          type: integer
                          example: 121
                        title:
                          type: string
                          example: 'El project manager en el laberinto: siempre con plan B'
                        content:
                          type: string
                          example: "¿Por qué el project manager nunca se asusta en un laberinto?\nPorque siempre tiene un \"plan de salida\"."
                        urlImage:
                          type: string
                          example: null
                        uploader:
                          type: string
                          example: '@raupulus'
                        options:
                          type: array
                          example: []
                  message:
                    type: string
                    example: 'Se devuelve 1 contenido aleatorio para el grupo Chistes de Programación de 126 contenidos totales.'
                    description: 'Mensaje descriptivo de la operación'
                    enum: []
                  meta:
                    type: object
                    properties:
                      group:
                        type: string
                        example: 'Chistes de Programación'
                        description: 'Título del grupo'
                        enum: []
                      group_slug:
                        type: string
                        example: chistes-devs
                        description: 'Slug del grupo'
                        enum: []
                      total_items:
                        type: integer
                        example: 126
                        description: 'Total de contenidos disponibles para este grupo'
                        enum: []
                    description: 'Metadatos adicionales de la respuesta'
        404:
          description: ''
          content:
            application/json:
              schema:
                type: object
                example:
                  success: false
                  message: 'No se encontraron contenidos para el grupo especificado'
                properties:
                  success:
                    type: boolean
                    example: false
                    description: 'Indica si la operación fue exitosa'
                    enum: []
                  message:
                    type: string
                    example: 'No se encontraron contenidos para el grupo especificado'
                    description: 'Mensaje descriptivo de la operación'
                    enum: []
        500:
          description: ''
          content:
            application/json:
              schema:
                type: object
                example:
                  success: false
                  message: 'Error al obtener contenidos del tipo especificado'
                properties:
                  success:
                    type: boolean
                    example: false
                    description: 'Indica si la operación fue exitosa'
                    enum: []
                  message:
                    type: string
                    example: 'Error al obtener contenidos del tipo especificado'
                    description: 'Mensaje descriptivo de la operación'
                    enum: []
      tags:
        - '📚 Contenidos'
    parameters:
      -
        in: path
        name: group_slug
        description: 'El slug del grupo de contenido.'
        example: chistes-devs
        required: true
        schema:
          type: string
  '/api/v1/user/{nick}/content/random':
    get:
      summary: 'Contenido en base a un usuario'
      operationId: contenidoEnBaseAUnUsuario
      description: 'Devuelve un contenido aleatorio de entre todos los que pertenezcan a un usuario.'
      parameters: []
      responses:
        200:
          description: ''
          content:
            application/json:
              schema:
                type: object
                example:
                  success: true
                  data:
                    -
                      id: 78
                      title: 'El lince: mascota oficial del backend'
                      content: "¿Cuál es el animal favorito de un programador backend?\nEl lince, siempre acechando en los servidores."
                      urlImage: null
                      uploader: '@raupulus'
                      options: []
                  message: 'Se devuelven 271 contenidos aleatorios para el usuario @raupulus'
                  meta:
                    user: raupulus
                    total_items: 271
                properties:
                  success:
                    type: boolean
                    example: true
                    description: 'Indica si la operación fue exitosa'
                    enum: []
                  data:
                    type: array
                    example:
                      -
                        id: 78
                        title: 'El lince: mascota oficial del backend'
                        content: "¿Cuál es el animal favorito de un programador backend?\nEl lince, siempre acechando en los servidores."
                        urlImage: null
                        uploader: '@raupulus'
                        options: []
                    description: 'Colección de contenidos aleatorios'
                    enum: []
                    items:
                      type: object
                      properties:
                        id:
                          type: integer
                          example: 78
                        title:
                          type: string
                          example: 'El lince: mascota oficial del backend'
                        content:
                          type: string
                          example: "¿Cuál es el animal favorito de un programador backend?\nEl lince, siempre acechando en los servidores."
                        urlImage:
                          type: string
                          example: null
                        uploader:
                          type: string
                          example: '@raupulus'
                        options:
                          type: array
                          example: []
                  message:
                    type: string
                    example: 'Se devuelven 271 contenidos aleatorios para el usuario @raupulus'
                    description: 'Mensaje descriptivo de la operación'
                    enum: []
                  meta:
                    type: object
                    properties:
                      user:
                        type: string
                        example: raupulus
                        description: 'Nick del usuario sobre el que se filtran los contenidos'
                        enum: []
                      total_items:
                        type: integer
                        example: 271
                        description: 'Número total de contenidos disponibles'
                        enum: []
                    description: 'Metadatos adicionales de la respuesta'
        404:
          description: ''
          content:
            application/json:
              schema:
                type: object
                example:
                  success: false
                  message: 'No se encontraron contenidos para el usuario especificado'
                properties:
                  success:
                    type: boolean
                    example: false
                    description: 'Indica si la operación fue exitosa'
                    enum: []
                  message:
                    type: string
                    example: 'No se encontraron contenidos para el usuario especificado'
                    description: 'Mensaje descriptivo de la operación'
                    enum: []
        500:
          description: ''
          content:
            application/json:
              schema:
                type: object
                example:
                  success: false
                  message: 'Error al obtener contenidos del usuario especificado'
                properties:
                  success:
                    type: boolean
                    example: false
                    description: 'Indica si la operación fue exitosa'
                    enum: []
                  message:
                    type: string
                    example: 'Error al obtener contenidos del usuario especificado'
                    description: 'Mensaje descriptivo de la operación'
                    enum: []
      tags:
        - '📚 Contenidos'
    parameters:
      -
        in: path
        name: nick
        description: 'El nick del usuario para filtrar por su contenido.'
        example: raupulus
        required: true
        schema:
          type: string
  /api/v1/suggestion/send:
    post:
      summary: 'Envía una sugerencia de chiste a la plataforma'
      operationId: envaUnaSugerenciaDeChisteALaPlataforma
      description: 'Se permiten máximo 10 sugerencias en 1 minuto.'
      parameters: []
      responses:
        201:
          description: ''
          content:
            application/json:
              schema:
                type: object
                example:
                  success: true
                  data: null
                  message: 'La sugerencia ha sido enviada correctamente.'
                properties:
                  success:
                    type: boolean
                    example: true
                    description: 'Indica si la operación fue exitosa'
                    enum: []
                  data:
                    type: string
                    example: null
                  message:
                    type: string
                    example: 'La sugerencia ha sido enviada correctamente.'
                    description: 'Mensaje descriptivo de la operación'
                    enum: []
        500:
          description: ''
          content:
            application/json:
              schema:
                type: object
                example:
                  success: false
                  message: 'Error al añadir sugerencia, si persiste contacta con el administrador'
                properties:
                  success:
                    type: boolean
                    example: false
                    description: 'Indica si la operación fue exitosa'
                    enum: []
                  message:
                    type: string
                    example: 'Error al añadir sugerencia, si persiste contacta con el administrador'
                    description: 'Mensaje descriptivo de la operación'
                    enum: []
      tags:
        - '💡 Sugerencias'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                nick:
                  type: string
                  description: 'Nombre de usuario o nick del autor de la sugerencia (máximo 25 caracteres, solo letras, números y guiones bajos). Must match the regex /^[a-zA-Z0-9_]+$/. El campo value debe ser menor que 25 caracteres.'
                  example: mi_usuario_123
                  nullable: false
                title:
                  type: string
                  description: 'Título de la sugerencia (máximo 255 caracteres). El campo value debe ser menor que 255 caracteres.'
                  example: 'Pájaros caminantes'
                  nullable: false
                content:
                  type: string
                  description: 'Contenido principal de la sugerencia (chiste, adivinanza, etc.) - máximo 1024 caracteres. El campo value debe ser menor que 1024 caracteres.'
                  example: '¿Por qué los pájaros vuelan hacia el sur? Porque caminando tardarían mucho.'
                  nullable: false
              required:
                - content
  /api/v1/report/send:
    post:
      summary: 'Envía un reporte sobre contenido de la plataforma'
      operationId: envaUnReporteSobreContenidoDeLaPlataforma
      description: 'Se permiten máximo 10 reportes en 1 minuto por usuario.'
      parameters: []
      responses:
        201:
          description: ''
          content:
            application/json:
              schema:
                type: object
                example:
                  success: true
                  data:
                    id: 1
                    title: 'Contenido inapropiado'
                    type: inappropriate_content
                    status: pending
                    content_id: 123
                    reporter_name: 'Juan Pérez'
                  message: 'El reporte ha sido enviado correctamente y será revisado por nuestro equipo.'
                properties:
                  success:
                    type: boolean
                    example: true
                    description: 'Indica si la operación fue exitosa'
                    enum: []
                  data:
                    type: object
                    properties:
                      id:
                        type: integer
                        example: 1
                      title:
                        type: string
                        example: 'Contenido inapropiado'
                      type:
                        type: string
                        example: inappropriate_content
                      status:
                        type: string
                        example: pending
                      content_id:
                        type: integer
                        example: 123
                      reporter_name:
                        type: string
                        example: 'Juan Pérez'
                    description: 'Datos del reporte creado'
                  message:
                    type: string
                    example: 'El reporte ha sido enviado correctamente y será revisado por nuestro equipo.'
                    description: 'Mensaje descriptivo de la operación'
                    enum: []
        422:
          description: ''
          content:
            application/json:
              schema:
                type: object
                example:
                  success: false
                  message: 'Error de validación'
                  errors:
                    content_id:
                      - 'El ID del contenido es requerido.'
                    title:
                      - 'El título del reporte es requerido.'
                properties:
                  success:
                    type: boolean
                    example: false
                    description: 'Indica si la operación fue exitosa'
                    enum: []
                  message:
                    type: string
                    example: 'Error de validación'
                    description: 'Mensaje descriptivo de la operación'
                    enum: []
                  errors:
                    type: object
                    properties:
                      content_id:
                        type: array
                        example:
                          - 'El ID del contenido es requerido.'
                        items:
                          type: string
                      title:
                        type: array
                        example:
                          - 'El título del reporte es requerido.'
                        items:
                          type: string
        500:
          description: ''
          content:
            application/json:
              schema:
                type: object
                example:
                  success: false
                  message: 'Error al enviar el reporte, si persiste contacta con el administrador'
                properties:
                  success:
                    type: boolean
                    example: false
                    description: 'Indica si la operación fue exitosa'
                    enum: []
                  message:
                    type: string
                    example: 'Error al enviar el reporte, si persiste contacta con el administrador'
                    description: 'Mensaje descriptivo de la operación'
                    enum: []
      tags:
        - '🚨 Reportes'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                content_id:
                  type: integer
                  description: 'ID del contenido a reportar.'
                  example: 123
                  nullable: false
                title:
                  type: string
                  description: 'Título del reporte (máximo 255 caracteres).'
                  example: 'Contenido inapropiado'
                  nullable: false
                type:
                  type: string
                  description: 'Tipo de reporte. Valores aceptados: spam|inappropriate_content|adult_content|hate_speech|harassment.'
                  example: inappropriate_content
                  nullable: true
                description:
                  type: string
                  description: 'Descripción detallada del reporte (máximo 1024 caracteres).'
                  example: 'Este contenido contiene lenguaje ofensivo'
                  nullable: true
                additional_info:
                  type: string
                  description: 'Información adicional sobre el reporte (máximo 1024 caracteres).'
                  example: 'Reportado por múltiples usuarios'
                  nullable: true
                reporter_name:
                  type: string
                  description: 'Nombre del reportador (si difiere del usuario autenticado).'
                  example: 'Juan Pérez'
                  nullable: true
                reporter_email:
                  type: string
                  description: 'Email del reportador (si difiere del usuario autenticado).'
                  example: juan@example.com
                  nullable: true
              required:
                - content_id
                - title
