API de Skillion

Lee y cambia tus propias skills, tareas y rutinas de time blocking desde tus scripts, atajos e integraciones. Incluida en Skillion Premium.

Solo Premium · JSON · Token Bearer

Empieza por tu primera llamada
URL base https://api.skillion.app/functions/v1/api/v1
En esta página

Tu primera llamada

  1. Saca tu clave en la app: Ajustes → toca 7 veces la versión → API para desarrolladores. Paso a paso, con todo detalle

    Ojo

    Necesitas Skillion Premium y una cuenta registrada (no de invitado). Sin Premium la fila sale con candado y abre la pantalla de suscripción.

  2. Pide tu perfil:

    curl
    export SKILLION_KEY="sk_live_…"   # la tuya, de la app
    
    curl https://api.skillion.app/functions/v1/api/v1/me \
      -H "Authorization: Bearer $SKILLION_KEY"
  3. Te devuelve tu nivel, XP, monedas y energía, y tus límites:

    Respuesta · ejemplo
    {
      "data": {
        "level": 7,
        "total_xp": 140,
        "xp_to_next_level": 350,
        "coins": 820,
        "energy_points": 64,
        "max_energy": 100,
        "health_points": 100,
        "max_health": 100,
        "nickname": "Luna",
        "updated_at": "2026-10-21T18:00:00Z"
      },
      "limits": { "per_minute": 120, "per_day": 10000, "page_max": 100 }
    }

Tu clave

  1. Abre Skillion y ve a Ajustes.

  2. Baja hasta el final y toca siete veces seguidas la línea «Versión …», con menos de 2 segundos entre toque y toque. El móvil vibra y sale «Opciones de desarrollador activadas».

  3. En Ajustes aparece una fila nueva: «API para desarrolladores». Ábrela.

  4. Toca «Crear clave», ponle un nombre y toca «Crear». Después toca «Copiar»: la clave solo se enseña una vez. Puedes tener hasta 5 activas y revocar cualquiera desde esa pantalla.

Ojo

Trata la clave como una contraseña: quien la tenga puede cambiar tus tareas. Si se te escapa, revócala en esa misma pantalla.

Autenticación

Manda la clave como token Bearer en cada petición. Todos los cuerpos van en JSON.

curl
curl https://api.skillion.app/functions/v1/api/v1/me \
  -H "Authorization: Bearer sk_live_…"

Completar una tarea no es inmediato

Ojo

El XP, las monedas, la energía y las rachas los calcula la app, así que completar por la API es una petición: recibes 202 al momento y tu móvil la aplica la próxima vez que Skillion sincroniza (al abrirla). Síguela en /v1/completions: pending → claimed → applied, o rejected con el motivo (already_completed, insufficient_energy…).

Las tareas de un pacto se completan con un check-in en la app y los malos hábitos nunca se completan: las dos dan 409.

Endpoints

MétodoRutaQué hace
Cuenta
GET /v1/me Tu nivel, XP, monedas, energía y los límites
Skills
GET /v1/skills Lista las skills
POST /v1/skills Crea una skill
GET /v1/skills/{id} Una skill
PATCH /v1/skills/{id} Cambia una skill
DELETE /v1/skills/{id} Archiva una skill
Tareas
GET /v1/tasks Lista las tareas, cada una con sus skills
POST /v1/tasks Crea una tarea
GET /v1/tasks/{id} Una tarea
PATCH /v1/tasks/{id} Cambia una tarea
DELETE /v1/tasks/{id} Borra o archiva una tarea
POST /v1/tasks/{id}/complete Pide a la app que la complete (202)
Completados
GET /v1/completions Tus peticiones de completar y qué pasó
Rutinas
GET /v1/routines Lista las rutinas, cada una con sus bloques
POST /v1/routines Crea una rutina con sus bloques
GET /v1/routines/{id} Una rutina
PATCH /v1/routines/{id} Cambia una rutina o sus bloques
DELETE /v1/routines/{id} Borra una rutina y sus bloques
Solo lectura
GET /v1/categories Tus categorías (solo lectura)
GET /v1/history Tu historial: completados, subidas de nivel… (solo lectura)

Listas y paginado

Las listas vienen del cambio más antiguo al más nuevo. Devuelve next_cursor como cursor hasta que sea null. Lo borrado y lo archivado no sale salvo que lo pidas.

ParámetroRegla
limitde 1 a 100, 50 por defecto
cursorel next_cursor de la página anterior
updated_sincefecha ISO: solo lo que cambió después
include_deletedtrue para traer también lo borrado (con deleted_at)
include_archivedtrue para traer también skills y tareas archivadas
category_id, statussolo tareas: filtra por categoría o estado
event_typesolo historial, por ejemplo taskCompleted

Campos de tarea que puedes poner

CampoRegla
titleobligatorio texto, 1–128
description texto hasta 2.000 o null
category_id una de tus categorías; por defecto, la primera predeterminada
skills [{"skill_id": "…", "xp": -100…100}], hasta 20; xp vale 10 por defecto, negativo resta XP
difficulty very_easy, easy, medium (por defecto), hard, very_hard
is_recurring true / false
recurrence_pattern daily, weekly, monthly, yearly, custom (obligatorio si es recurrente)
custom_days "1,3,5": 1 = lunes … 7 = domingo (para custom)
deadline fecha ISO, solo para tareas no recurrentes
Ver 15 campos más
CampoRegla
priority1–5, 3 por defecto
energy_cost-50…50, -1 por defecto (negativo gasta energía, positivo la da)
coins0–100, 10 por defecto
health_effect-50…50
estimated_durationsegundos, 0–86.400
recurrence_target1–99 veces por periodo
recurrence_day_of_month1–31 (monthly, yearly)
recurrence_month1–12 (yearly)
recurrence_end_datefecha ISO
daily_deadline_time"HH:mm"
reminder_modeauto (por defecto), at_deadline, before_15, before_60, morning, custom, none
reminder_minute0–1439, minuto del día (con custom)
is_penaltytrue: pierdes recompensa si pasa el plazo
iconun emoji, o assets/images/icons/<nombre>.png
color#RRGGBB

Solo title es obligatorio. Lo demás (XP, nivel, estado, monedas ganadas) lo calcula la app y es de solo lectura. Un campo desconocido da 422, así que una errata nunca pasa desapercibida.

Campos de skill que puedes poner

CampoRegla
nametexto, 1–32 (obligatorio)
descriptiontexto hasta 500 o null
iconun emoji, o assets/images/icons/<nombre>.png
color#RRGGBB o null
is_activetrue / false

level, total_xp (el XP dentro del nivel actual) y las rachas son de solo lectura. Las cuentas gratis mantienen 3 skills activas, pero la API en sí es solo Premium.

Rutinas y sus bloques

Una rutina es un día de la pantalla de time blocking («Lunes», «Día de trabajo»…) con sus bloques dentro. Una semana entera son siete POST /v1/routines, uno por día.

Rutina

CampoRegla
nametexto, 1–64 (obligatorio)
blockslista de hasta 96 bloques (abajo)
is_defaulttrue: la que usa la app por defecto; marcar una desmarca las demás. Si aún no tienes ninguna, la nueva lo es
iconun emoji, o assets/images/icons/<nombre>.png, o null
color#RRGGBB o null

Cada bloque de blocks

CampoRegla
start_minuteminutos desde medianoche, 0–2879 de 5 en 5 (420 = 07:00; 1440 o más es el día siguiente, para una rutina que pasa de medianoche)
duration_minute5–1440 de 5 en 5
titletexto, 1–128; obligatorio si el bloque no lleva task_id
task_iduna de tus tareas: el bloque es esa tarea
notetexto hasta 2.000 o null
iconun emoji, o assets/images/icons/<nombre>.png, o null
color#RRGGBB o null
is_pinnedtrue: «Empezar ahora» no lo mueve
idsolo para cambiar un bloque que la rutina ya tiene

blocks es siempre la lista entera: un bloque con id se actualiza, uno sin id se crea y el que no mandes se borra. Si no mandas blocks en un PATCH, se quedan como están. Los bloques vuelven con start_time y end_time («07:30») para leerlos fácil.

Ojo

Qué rutina enseña hoy tu móvil se elige en el móvil: la API crea y cambia rutinas, pero no cambia la que ves.

Errores

Los errores tienen siempre la misma forma. details dice qué campo no es válido.

JSON
{
  "error": {
    "code": "invalid_field",
    "message": "Some fields are not valid.",
    "details": { "custom_days": "must be weekdays like \"1,3,5\" …" }
  }
}
HTTPCódigoQué hace
400invalid_request / invalid_jsonparámetro o cuerpo incorrecto
401unauthorizedclave ausente, mal formada o revocada
403premium_requiredla cuenta no es Premium
404not_foundno existe (o no es tuyo)
409pact_task / bad_habit / too_many_pendingese cambio es de la app
413payload_too_largecuerpo de más de 64 KB
422invalid_fieldmira details
429rate_limitedespera retry-after segundos
405method_not_allowedese método no existe en esa ruta
500internalfallo nuestro: prueba más tarde

Límites

120 peticiones por minuto
por cuenta, todas tus claves juntas
10.000 peticiones al día
por cuenta, el día empieza a las 00:00 UTC
100 elementos por página
50 por defecto
64 KB por cuerpo

Si te pasas recibes 429 con la cabecera retry-after (segundos). Cada respuesta lleva x-ratelimit-limit y x-ratelimit-remaining.

Borrar

DELETE hace lo mismo que la app: las skills y las tareas recurrentes se archivan (su historial se queda) y las tareas sueltas se borran, y una rutina se borra con sus bloques. En todos los casos desaparecen de tu móvil en el siguiente sync.

Conviene saber

  • Los cambios llegan a tu móvil en el siguiente sync, normalmente al abrir la app.
  • Si editas la misma tarea en el móvil antes de que sincronice, gana el móvil.
  • Las tareas recurrentes reciben su próxima fecha desde tu móvil, que sabe tu zona horaria y tu hora de reinicio.
  • Las fechas van en ISO 8601 con zona horaria, por ejemplo 2026-10-21T18:00:00Z.

Ejemplos

Crear una tarea recurrente unida a una skill

curl
curl -X POST https://api.skillion.app/functions/v1/api/v1/tasks \
  -H "Authorization: Bearer $SKILLION_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "title": "Gym",
    "is_recurring": true,
    "recurrence_pattern": "custom",
    "custom_days": "1,3,5",
    "difficulty": "hard",
    "skills": [{ "skill_id": "<skill id>", "xp": 20 }]
  }'

Completarla (desde un atajo, un cron, un botón)

curl
curl -X POST https://api.skillion.app/functions/v1/api/v1/tasks/<task id>/complete \
  -H "Authorization: Bearer $SKILLION_KEY"

# 202 → { "data": { "id": "…", "status": "pending", … } }

Leer todo lo que cambió desde ayer

JavaScript
const since = new Date(Date.now() - 86_400_000).toISOString()
let cursor = null
do {
  const url = new URL('https://api.skillion.app/functions/v1/api/v1/tasks')
  url.searchParams.set('updated_since', since)
  if (cursor) url.searchParams.set('cursor', cursor)
  const res = await fetch(url, { headers: { Authorization: `Bearer ${process.env.SKILLION_KEY}` } })
  const page = await res.json()
  for (const task of page.data) console.log(task.title, task.status)
  cursor = page.next_cursor
} while (cursor)

Organizar la semana: una rutina por día

JavaScript
const days = ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', 'Sunday']
for (const name of days) {
  const weekend = name === 'Saturday' || name === 'Sunday'
  const res = await fetch('https://api.skillion.app/functions/v1/api/v1/routines', {
    method: 'POST',
    headers: { Authorization: `Bearer ${process.env.SKILLION_KEY}`, 'Content-Type': 'application/json' },
    body: JSON.stringify({
      name,
      blocks: [
        { start_minute: weekend ? 540 : 420, duration_minute: 30, title: 'Read' },
        { start_minute: 1080, duration_minute: 60, title: 'Gym', color: '#F29092' },
        { start_minute: 1380, duration_minute: 60, title: 'Wind down' },
      ],
    }),
  })
  if (!res.ok) console.error(name, (await res.json()).error)
}

¿Dudas? Escríbenos desde la página de contacto. Contacto