🐾 Tin Tails API Docs

Documentación técnica de funciones, payloads JSON a enviar y respuestas del servidor

● Servidor Activo

Autenticación (/api/auth)

POST /api/auth/register Registro de nuevo usuario Público
Qué hace: Registra un nuevo usuario en la base de datos con contraseña encriptada (bcrypt), genera el Token JWT de sesión y dispara el correo de bienvenida vía Mailgun.
Objeto Body a Enviar (JSON):
{
  "email": "usuario@tintails.com",
  "password": "password123",
  "full_name": "María García",
  "role": "user"
}
Respuesta del Servidor (JSON):
{
  "success": 1,
  "message": {
    "message": "Usuario registrado con éxito",
    "user": {
      "id": "2wwdx3qaAoyYuUPFcNUhQy",
      "email": "usuario@tintails.com",
      "full_name": "María García",
      "role": "user"
    },
    "token": "eyJhbGciOiJIUzI1Ni..."
  }
}
POST /api/auth/login Iniciar Sesión Público
Qué hace: Valida el correo y la contraseña contra MySQL. Si es correcto, devuelve la información del usuario y su token JWT firmado de sesión.
Objeto Body a Enviar (JSON):
{
  "email": "usuario@tintails.com",
  "password": "password123"
}
Respuesta del Servidor (JSON):
{
  "success": 1,
  "message": {
    "user": {
      "id": "2wwdx3qaAoyYuUPFcNUhQy",
      "email": "usuario@tintails.com",
      "full_name": "María García",
      "role": "user"
    },
    "token": "eyJhbGciOiJIUzI1Ni..."
  }
}
GET /api/auth/verify Verificar sesión activa Bearer JWT
Qué hace: Valida el token JWT enviado en la cabecera Authorization: Bearer <token> al recargar la aplicación web.
Headers requeridos:
Authorization: Bearer eyJhbGciOiJIUzI1Ni...
Respuesta del Servidor (JSON):
{
  "success": 1,
  "message": {
    "user": {
      "id": "2wwdx3qaAoyYuUPFcNUhQy",
      "email": "usuario@tintails.com",
      "full_name": "María García",
      "role": "user"
    },
    "token": "eyJhbGciOiJIUzI1..."
  }
}

Libros y Catálogo (/api/books)

GET /api/books Obtener catálogo del Home Público
Qué hace: Retorna el listado completo de cuentos publicados para el catálogo principal del sitio web. Permite filtrar opcionalmente por ?category_id=cat_emociones o ?is_free=true.
Parámetros Query (Opcionales):
GET /api/books?category_id=cat_emociones&is_free=true
Respuesta del Servidor (JSON Array):
{
  "success": 1,
  "message": [
    {
      "id": "autocontrol",
      "title": "El secreto de Martina y el río de la calma",
      "subtitle": "Cómo dominar los impulsos negativos",
      "price": 0,
      "original_price": 40000,
      "age_range": "3-8 años",
      "category_id": "cat_emociones",
      "cover_image": "/assets/covers/cover-autocontrol.jpg",
      "description": "Martina aprende a respirar...",
      "is_free": 1,
      "category_name": "Emociones & Autoestima"
    }
  ]
}
GET /api/books/:id Obtener detalle de un cuento Público
Qué hace: Devuelve la ficha de detalle de un libro en específico incluyendo precios, edad recomendada y portada.
URL Parameter:
GET /api/books/autocontrol
Respuesta del Servidor (JSON):
{
  "success": 1,
  "message": {
    "id": "autocontrol",
    "title": "El secreto de Martina y el río de la calma",
    "price": 0,
    "category_name": "Emociones & Autoestima"
  }
}
GET /api/books/:id/pages Páginas de lectura para el visor Público
Qué hace: Devuelve la secuencia de páginas ordenadas (texto, imagen de ilustración y audio) para reproducirse en el visor flipbook.
URL Parameter:
GET /api/books/autocontrol/pages
Respuesta del Servidor (JSON Array):
{
  "success": 1,
  "message": [
    {
      "id": "page_1",
      "book_id": "autocontrol",
      "page_number": 1,
      "text": "Había una vez en un valle lejano...",
      "image_url": "/assets/pages/autocontrol_1.jpg",
      "audio_url": "/assets/audio/autocontrol_1.mp3"
    }
  ]
}
POST /api/books Agregar un nuevo libro Bearer JWT
Qué hace: Agrega un nuevo producto/cuento al catálogo especificando precios, categoría e imagen de portada.
Objeto Body a Enviar (JSON):
{
  "title": "Las aventuras de Moti",
  "subtitle": "Un viaje por las nubes",
  "price": 40000.00,
  "original_price": 120000.00,
  "age_range": "3-8 años",
  "category_id": "cat_emociones",
  "cover_image": "/assets/uploads/portada_moti.jpg",
  "description": "Una historia para fortalecer la autoconfianza.",
  "is_free": 0
}
Respuesta del Servidor (JSON):
{
  "success": 1,
  "message": {
    "message": "Libro creado correctamente",
    "book": {
      "id": "eXp6XPvHES6Utgqv4ejKL3",
      "title": "Las aventuras de Moti",
      "price": 40000,
      "cover_image": "/assets/uploads/portada_moti.jpg"
    }
  }
}
PUT /api/books/:id Editar nombre y precios Bearer JWT
Qué hace: Permite editar el título, precio regular, precio promocional, descripción o estado de cualquier libro existente.
Objeto Body a Enviar (JSON):
{
  "title": "Las aventuras de Moti (Edición Especial)",
  "price": 35000.00,
  "original_price": 100000.00
}
Respuesta del Servidor (JSON):
{
  "success": 1,
  "message": "Libro actualizado correctamente."
}

Stripe y Pagos (/api/payments)

POST /api/payments/create-checkout Crear sesión de Stripe Checkout Público
Qué hace: Genera el clientSecret de la sesión en Stripe para mostrar el formulario de tarjeta de crédito embebido en la web.
Objeto Body a Enviar (JSON):
{
  "priceId": "price_12345",
  "quantity": 1,
  "customerEmail": "usuario@tintails.com",
  "userId": "2wwdx3qaAoyYuUPFcNUhQy",
  "metadata": {
    "bookIds": "autocontrol,responsabilidad",
    "formatType": "digital"
  }
}
Respuesta del Servidor (JSON):
{
  "clientSecret": "cs_test_a1b2c3d4..."
}

Biblioteca del Usuario (/api/purchases)

GET /api/purchases/my-library Cuentos comprados por el usuario Bearer JWT
Qué hace: Consulta en MySQL todas las compras registradas para el usuario autenticado y le otorga acceso a sus cuentos en "Mi Biblioteca".
Headers requeridos:
Authorization: Bearer eyJhbGciOiJIUzI1Ni...
Respuesta del Servidor (JSON Array):
{
  "success": 1,
  "message": [
    {
      "id": "pur_987",
      "book_id": "responsabilidad",
      "title": "Lucas y el jardín de las Responsabilidades",
      "format_type": "digital",
      "amount_paid": 40000,
      "status": "completado",
      "purchase_date": "2026-08-07T03:37:32.000Z"
    }
  ]
}

Subida de Archivos (/api/admin)

POST /api/admin/upload Subir portada o imagen Bearer JWT
Qué hace: Recibe una imagen mediante Form-Data (campo file), la guarda físicamente en files/uploads/ y retorna la URL estática accesible para ser usada en los cuentos.
Form Data a Enviar:
Content-Type: multipart/form-data
field: file (Binary File)
Respuesta del Servidor (JSON):
{
  "success": 1,
  "message": {
    "message": "Archivo subido con éxito",
    "url": "/assets/uploads/emh6MkdKLUYnVgHUDzkGS7.jpg"
  }
}