API de Cron Jobs
API REST
Sección titulada «API REST»Leer necesita el alcance cron:read. Disparar, pausar y reanudar necesitan
cron:write. Un administrador tiene ambos. También los tiene una persona cuyo rol los
declare, y una clave de API creada con ellos, que es lo que debería llevar un
planificador externo:
rebase api-keys create -n "Scheduler" --scopes cron:read,cron:writeConsulta Roles y alcances.
| Método | Ruta | Descripción |
|---|---|---|
GET |
/api/admin/cron |
Listar todos los cron jobs registrados |
GET |
/api/admin/cron/:id |
Obtener el estado de una tarea individual |
POST |
/api/admin/cron/:id/trigger |
Activar manualmente una tarea — 409 mientras ya se está ejecutando. ?async=1 responde 202 en cuanto la ejecución ha empezado |
GET |
/api/admin/cron/:id/logs |
Obtener el historial de ejecución (?limit=N), de los últimos 30 días. 503 cuando no se puede leer rebase.cron_logs, en lugar de un historial vacío |
PUT |
/api/admin/cron/:id |
Pausar o reanudar una tarea en todos los procesos ({ "enabled": false }); null vuelve a seguir el código |
Ejemplo: Listar todas las tareas
Sección titulada «Ejemplo: Listar todas las tareas»$TOKEN es un token de acceso de una cuenta que tiene cron:read: inicia sesión y usa el accessToken devuelto en la respuesta de inicio de sesión. Una clave de API que tenga el alcance funciona igual. $API_URL es lo que haya impreso rebase dev; el puerto se deriva de la ruta del proyecto, por lo que no es fijo.
curl -H "Authorization: Bearer $TOKEN" "$API_URL/api/admin/cron"{ "jobs": [ { "id": "health-check", "name": "System Health Check", "schedule": "*/5 * * * *", "enabled": true, "state": "idle", "totalRuns": 12, "totalFailures": 0, "lastRunAt": "2026-04-24T08:15:00.000Z", "nextRunAt": "2026-04-24T08:20:00.000Z", "lastDurationMs": 3 } ]}Tareas que no están ahí
Sección titulada «Tareas que no están ahí»Una tarea que nunca se dispara no aparece en jobs (nada la registró), por lo que «falta mi cron» y «mi cron nunca se ejecutará» parecen idénticos desde este endpoint a menos que indique lo contrario. Y lo hace:
{ "jobs": [], "skipped": 2, "rejected": [ { "id": "nightly-report", "name": "Nightly report", "schedule": "0 0 3 * * *", "reason": "Expected 5 fields, got 6" } ], "note": "1 cron file(s) failed to load and 1 job(s) were refused — NOT scheduled. See `rejected` for the reason; the server log has the rest."}rejected nombra la tarea y el motivo. Un archivo que falló al cargar solo tiene un recuento: el fallo ocurrió antes de que hubiera una tarea que nombrar, por lo que el motivo está en los registros del servidor.
La entrada más común aquí es la de arriba: seis campos, a partir de una expresión copiada de una herramienta que admite segundos. Rebase acepta cinco; elimina el primer campo. Un timeoutSeconds de cero, un número negativo o NaN también aparece aquí.
Ejemplo: Activar una tarea manualmente
Sección titulada «Ejemplo: Activar una tarea manualmente»curl -X POST -H "Authorization: Bearer $TOKEN" \ "$API_URL/api/admin/cron/health-check/trigger"Mientras la tarea se está ejecutando — aquí o en cualquier otro proceso —, la
respuesta es 409 con el código CRON_JOB_ALREADY_EXECUTING; consulta
Protección de concurrencia.
La llamada espera a que termine la ejecución y responde 200 con su log. Para una tarea que se ejecuta
más tiempo del que un proxy delante del servidor mantiene una petición (muchos lo hacen a los 60 segundos), añade
?async=1. La respuesta es entonces 202 en cuanto la ejecución ha empezado:
curl -X POST -H "Authorization: Bearer $TOKEN" \ "$API_URL/api/admin/cron/nightly-report/trigger?async=1"{ "accepted": true, "startedAt": "2026-04-24T08:21:04.512Z", "job": { "id": "nightly-report", "state": "running" }}La ejecución continúa tras la respuesta. Su resultado está en GET /api/admin/cron/:id/logs, como la
entrada con "manual": true y el mismo startedAt. Una ejecución que no puede empezar sigue respondiendo
409. ?async acepta 1, true, 0 o false; cualquier otro valor es un 400.
Pausar una tarea
Sección titulada «Pausar una tarea»Una pausa desde Studio o con
PUT /api/admin/cron/:id se aplica a todos los procesos y se mantiene tras
reinicios y redespliegues; { "enabled": null } devuelve la tarea al enabled
que declara su archivo. Cómo la lee cada réplica, y qué ocurre cuando una no
puede, está en Cron entre instancias.
SDK tipado
Sección titulada «SDK tipado»El SDK tipado de Rebase expone un espacio de nombres cron para todas las operaciones:
import { createRebaseClient } from "@rebasepro/client";
const client = createRebaseClient({ baseUrl: import.meta.env.VITE_API_URL });
// List all jobs, and the ones that did not registerconst { jobs, rejected } = await client.cron.listJobs();
// Get a single jobconst { job } = await client.cron.getJob("health-check");
// Trigger manually, and wait for the runconst { log, job: updated } = await client.cron.triggerJob("health-check");
// Trigger manually, and answer once the run has startedconst { startedAt } = await client.cron.triggerJob("nightly-report", { async: true });
// View execution historyconst { logs } = await client.cron.getJobLogs("health-check", { limit: 10 });
// Enable or disableawait client.cron.toggleJob("health-check", false); // pauseawait client.cron.toggleJob("health-check", true); // resumetriggerJob() espera a que termine la ejecución y responde con su log. Un proxy delante del
servidor puede cortar la respuesta de un trabajo largo (muchos lo hacen a los 60 segundos) mientras la
ejecución sigue su curso. Para un trabajo así pasa { async: true }: la llamada responde en cuanto la ejecución ha empezado,
y getJobLogs() tiene el resultado, como la entrada con manual: true y el startedAt devuelto.
listJobs() tiene el tipo CronJobListing: jobs, más los campos skipped,
rejected y note descritos en Tareas que no están ahí.