Cron Jobs (totalum-sdk/cron)
import … from 'totalum-sdk/cron' — or the same namespace on totalum from 'totalum-sdk'. Install, configuration and errors: Totalum SDK.
Run a route of your own app on a schedule: every night at 8:00, every 15 minutes, the first day of the month. Totalum calls the URL you give (on the project's own published host) at each tick and records every run. Use it for reports, reminders, clean-ups and long tasks done in steps. Jobs run against the published site, so publish the project first. Each run costs a small fraction of a credit; the number of jobs and the shortest interval depend on the plan.
await totalum.cron.create({
name: 'daily-report',
schedule: '0 8 * * *',
timezone: 'Europe/Madrid',
request: { method: 'POST', url: 'https://acme.totalum.app/api/cron/report' },
});| Method or type | What it does |
|---|---|
totalumCron | Creates the cron namespace (the same object as totalum.cron, scope cron): HTTP jobs against the project's own host, fired by Totalum's Scheduler; limits per plan (429 CRON_LIMIT_REACHED {limit, plan}, 400 INVALID_SCHEDULE {minIntervalSeconds}). |
cron.create | Creates a job that calls a route of your own app on a schedule — a cron expression ('0 8 * * *') or { everyMinutes: 15 }. |
cron.list | Every job of the project, both environments. |
cron.get | One job, or null when the project has no job with this id. |
cron.update | Changes any field of a job (schedule, request, enabled, timezone, …); fields you leave out keep their value. |
cron.delete | Deletes a job and its run history. |
cron.pause | Stops a job from firing until resume (the same as update(id, { enabled: false })). |
cron.resume | Lets a paused job fire again — also one paused after failing runs (paused_failures) once its route is fixed. |
cron.runs | A job's executions of the last 30 days, newest first: when each ran, the HTTP status your route answered and how long it took. |
cron.trigger | Fires a job now, outside its schedule — a "Run now" button, or to test a new job. |
CronJob | A scheduled job. |
CronJobInput | A job for cron.create(). |
CronJobPatch | The fields cron.update() changes; each is optional and means the same as in cron.create(). |
CronRun | One execution of a job. |
CronRunsPage | One page of cron.runs(). |
#totalumCron
totalumCron(options?: TotalumClientOptions): TotalumCronCreates the cron namespace (the same object as totalum.cron, scope cron): HTTP jobs against the project's own host,
fired by Totalum's Scheduler; limits per plan (429 CRON_LIMIT_REACHED {limit, plan}, 400 INVALID_SCHEDULE {minIntervalSeconds}). Each run costs a small fraction of a credit. timezone (IANA) reads the schedule on that zone's clock, daylight
saving included; pauseAfterFailures (1–100, default 3; null = never) sets how many failed runs in a row pause it.
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
options | TotalumClientOptions | no | The project key, API URL and environment; each falls back to its environment variable. |
options.key | string | no | Project key tlm_pk_…; default TOTALUM_PROJECT_KEY. Server-side only. |
options.apiUrl | string | no | The Totalum API's URL: default TOTALUM_SDK_API_URL, else https://sdk-api.totalum.app. |
options.env | 'dev' | 'live' | no | Sent as x-totalum-env on every call (the database it targets, and dev vs live usage); default TOTALUM_ENV, else live. |
Returns TotalumCron — The cron namespace: the methods below.
Example
import { totalumCron } from 'totalum-sdk/cron';
const cron = totalumCron();
const jobs = await cron.list();The namespace's type is exported as TotalumCron (import type { TotalumCron } from 'totalum-sdk/cron').
#cron.create
cron.create(input: CronJobInput): Promise<CronJob>Creates a job that calls a route of your own app on a schedule — a cron expression ('0 8 * * *') or
{ everyMinutes: 15 }. The URL must be the project's own https:// host: the published site for a live job,
the preview for a dev one (without env, the URL decides). Each call is signed by Totalum (the template's cron
routes check it) and recorded in runs().
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
input | CronJobInput | yes | The name, schedule, request and options. |
input.name | string | yes | A name of yours (daily-report). Allowed: at least 1 character, at most 64 characters. |
input.schedule | string | { everyMinutes } | yes | When it runs: a 5-field cron expression ("0 8 * * *" = 08:00 every day, "*/15 * * * *" = every 15 minutes) or { everyMinutes: n }. The plan sets the shortest interval. |
input.schedule.everyMinutes | number | yes | Run every this many minutes. Allowed: > 0. |
input.request | { method, url, headers?, body?, timeoutMs? } | yes | The HTTP call each run makes. |
input.request.method | 'GET' | 'POST' | yes | GET or POST. |
input.request.url | string | yes | A URL on the project's own https:// host (the published site for live, the preview for dev). Allowed: a URL. |
input.request.headers | Record<string, string> | no | Extra headers to send. |
input.request.body | string | no | The body of a POST. Allowed: at most 65536 characters. |
input.request.timeoutMs | number | no | How long a run may take. Default 30 s, at most 30 s. Allowed: > 0, ≤ 30000. |
input.enabled | boolean | no | false creates it paused. Default true. |
input.description | string | no | A note of yours. |
input.env | 'dev' | 'live' | no | live (the published site) or dev (the preview). Default: the environment of request.url. |
input.timezone | string | no | An IANA time zone (Europe/Madrid): the schedule reads that zone's clock, daylight saving included. Default UTC. Allowed: at least 1 character, at most 64 characters. |
input.pauseAfterFailures | number | null | no | Pause the job after this many failed runs in a row. Default 3; null or 0 never pauses. Allowed: ≥ 0, ≤ 100. |
Returns Promise<CronJob> — The new job.
| Field | Type | Always present | Description |
|---|---|---|---|
id | string | yes | The job id (cj_…). |
name | string | yes | A name of yours (daily-report). Allowed: at least 1 character, at most 64 characters. |
schedule | string | { everyMinutes } | yes | When it runs: a 5-field cron expression ("0 8 * * *" = 08:00 every day, "*/15 * * * *" = every 15 minutes) or { everyMinutes: n }. The plan sets the shortest interval. |
schedule.everyMinutes | number | yes | Run every this many minutes. Allowed: > 0. |
request | { method, url, headers?, body?, timeoutMs? } | yes | The HTTP call each run makes. |
request.method | 'GET' | 'POST' | yes | GET or POST. |
request.url | string | yes | A URL on the project's own https:// host (the published site for live, the preview for dev). Allowed: a URL. |
request.headers | Record<string, string> | no | Extra headers to send. |
request.body | string | no | The body of a POST. Allowed: at most 65536 characters. |
request.timeoutMs | number | no | How long a run may take. Default 30 s, at most 30 s. Allowed: > 0, ≤ 30000. |
enabled | boolean | yes | false creates it paused. Default true. |
status | 'active' | 'paused' | 'paused_failures' | yes | active, paused (by you) or paused_failures (after too many failed runs; fix the route and resume). |
nextRunAt | string | null | yes | When it runs next, or null while paused. |
createdAt | string | yes | When it was created. |
env | 'dev' | 'live' | yes | live (the published site) or dev (the preview). Default: the environment of request.url. |
pauseAfterFailures | number | null | yes | Failed runs in a row before it pauses; null = never. Allowed: ≥ 0, ≤ 100. |
lastRun | { at, status, latencyMs } | no | The latest run. |
lastRun.at | string | yes | When it ran. |
lastRun.status | number | 'timeout' | 'error' | 'skipped' | yes | The HTTP status your route answered, or timeout, error (no answer) or skipped (cron was switched off). |
lastRun.latencyMs | number | yes | How long it took. |
description | string | no | A note of yours. |
timezone | string | no | An IANA time zone (Europe/Madrid): the schedule reads that zone's clock, daylight saving included. Default UTC. Allowed: at least 1 character, at most 64 characters. |
Errors — besides the errors every call can throw:
| Code | HTTP | When |
|---|---|---|
INVALID_SCHEDULE | 400 | Not a valid schedule, or it fires more often than the plan allows; details.minIntervalSeconds. |
CRON_URL_NOT_ALLOWED | 403 | The URL is not the project's own https:// host for that environment; details.allowedHost. |
CRON_REQUIRES_PUBLISHED_PROJECT | 403 | A live job, but the project is not published yet. |
CRON_LIMIT_REACHED | 429 | The plan's number of jobs per environment is reached; details.limit. |
ENGINE_UNAVAILABLE | 502 | The scheduler is unavailable; retry shortly. |
Example
const job = await totalum.cron.create({
name: 'daily-report',
schedule: '0 8 * * *', // 08:00 in Madrid all year
timezone: 'Europe/Madrid',
request: { method: 'POST', url: 'https://acme.totalum.app/api/cron/report' },
});Result:
{
"id": "cj_01M4P1F0R7T2Y9U4I6O3P8A5SD",
"name": "daily-report",
"schedule": "0 8 * * *",
"request": { "method": "POST", "url": "https://acme.totalum.app/api/cron/report" },
"enabled": true,
"status": "active",
"nextRunAt": "2026-10-12T06:00:00.000Z",
"createdAt": "2026-10-11T18:30:00.000Z",
"env": "live",
"timezone": "Europe/Madrid",
"pauseAfterFailures": 3
}#cron.list
cron.list(): Promise<CronJob[]>Every job of the project, both environments. Free.
Returns Promise<CronJob[]> — The jobs.
Each item:
| Field | Type | Always present | Description |
|---|---|---|---|
id | string | yes | The job id (cj_…). |
name | string | yes | A name of yours (daily-report). Allowed: at least 1 character, at most 64 characters. |
schedule | string | { everyMinutes } | yes | When it runs: a 5-field cron expression ("0 8 * * *" = 08:00 every day, "*/15 * * * *" = every 15 minutes) or { everyMinutes: n }. The plan sets the shortest interval. |
schedule.everyMinutes | number | yes | Run every this many minutes. Allowed: > 0. |
request | { method, url, headers?, body?, timeoutMs? } | yes | The HTTP call each run makes. |
request.method | 'GET' | 'POST' | yes | GET or POST. |
request.url | string | yes | A URL on the project's own https:// host (the published site for live, the preview for dev). Allowed: a URL. |
request.headers | Record<string, string> | no | Extra headers to send. |
request.body | string | no | The body of a POST. Allowed: at most 65536 characters. |
request.timeoutMs | number | no | How long a run may take. Default 30 s, at most 30 s. Allowed: > 0, ≤ 30000. |
enabled | boolean | yes | false creates it paused. Default true. |
status | 'active' | 'paused' | 'paused_failures' | yes | active, paused (by you) or paused_failures (after too many failed runs; fix the route and resume). |
nextRunAt | string | null | yes | When it runs next, or null while paused. |
createdAt | string | yes | When it was created. |
env | 'dev' | 'live' | yes | live (the published site) or dev (the preview). Default: the environment of request.url. |
pauseAfterFailures | number | null | yes | Failed runs in a row before it pauses; null = never. Allowed: ≥ 0, ≤ 100. |
lastRun | { at, status, latencyMs } | no | The latest run. |
lastRun.at | string | yes | When it ran. |
lastRun.status | number | 'timeout' | 'error' | 'skipped' | yes | The HTTP status your route answered, or timeout, error (no answer) or skipped (cron was switched off). |
lastRun.latencyMs | number | yes | How long it took. |
description | string | no | A note of yours. |
timezone | string | no | An IANA time zone (Europe/Madrid): the schedule reads that zone's clock, daylight saving included. Default UTC. Allowed: at least 1 character, at most 64 characters. |
Errors — besides the errors every call can throw:
| Code | HTTP | When |
|---|---|---|
ENGINE_UNAVAILABLE | 502 | The scheduler is unavailable; retry shortly. |
Example
const jobs = await totalum.cron.list();Result:
[
{
"id": "cj_01M4P1F0R7T2Y9U4I6O3P8A5SD",
"name": "daily-report",
"schedule": "0 8 * * *",
"request": { "method": "POST", "url": "https://acme.totalum.app/api/cron/report" },
"enabled": true,
"status": "active",
"nextRunAt": "2026-10-12T06:00:00.000Z",
"lastRun": { "at": "2026-10-11T06:00:00.412Z", "status": 200, "latencyMs": 812 },
"createdAt": "2026-10-01T18:30:00.000Z",
"env": "live",
"timezone": "Europe/Madrid",
"pauseAfterFailures": 3
}
]#cron.get
cron.get(id: string): Promise<CronJob | null>One job, or null when the project has no job with this id. Free.
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
id | string | yes | The job's id (cj_…). |
Returns Promise<CronJob \| null> — The job, or null.
Errors — besides the errors every call can throw:
| Code | HTTP | When |
|---|---|---|
ENGINE_UNAVAILABLE | 502 | The scheduler is unavailable; retry shortly. |
Example
const job = await totalum.cron.get('cj_01M4P1F0R7T2Y9U4I6O3P8A5SD');Result:
{ "id": "cj_01M4P1F0R7T2Y9U4I6O3P8A5SD", "name": "daily-report", "status": "active", "nextRunAt": "2026-10-12T06:00:00.000Z", … }#cron.update
cron.update(id: string, patch: CronJobPatch): Promise<CronJob>Changes any field of a job (schedule, request, enabled, timezone, …); fields you leave out keep their
value. The same checks as create apply.
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
id | string | yes | The job's id. |
patch | CronJobPatch | yes | The fields to change. |
patch.name | string | no | A name of yours (daily-report). Allowed: at least 1 character, at most 64 characters. |
patch.schedule | string | { everyMinutes } | no | When it runs: a 5-field cron expression ("0 8 * * *" = 08:00 every day, "*/15 * * * *" = every 15 minutes) or { everyMinutes: n }. The plan sets the shortest interval. |
patch.schedule.everyMinutes | number | yes | Run every this many minutes. Allowed: > 0. |
patch.request | { method, url, headers?, body?, timeoutMs? } | no | The HTTP call each run makes. |
patch.request.method | 'GET' | 'POST' | yes | GET or POST. |
patch.request.url | string | yes | A URL on the project's own https:// host (the published site for live, the preview for dev). Allowed: a URL. |
patch.request.headers | Record<string, string> | no | Extra headers to send. |
patch.request.body | string | no | The body of a POST. Allowed: at most 65536 characters. |
patch.request.timeoutMs | number | no | How long a run may take. Default 30 s, at most 30 s. Allowed: > 0, ≤ 30000. |
patch.enabled | boolean | no | false creates it paused. Default true. |
patch.description | string | no | A note of yours. |
patch.env | 'dev' | 'live' | no | live (the published site) or dev (the preview). Default: the environment of request.url. |
patch.timezone | string | no | An IANA time zone (Europe/Madrid): the schedule reads that zone's clock, daylight saving included. Default UTC. Allowed: at least 1 character, at most 64 characters. |
patch.pauseAfterFailures | number | null | no | Pause the job after this many failed runs in a row. Default 3; null or 0 never pauses. Allowed: ≥ 0, ≤ 100. |
Returns Promise<CronJob> — The updated job.
| Field | Type | Always present | Description |
|---|---|---|---|
id | string | yes | The job id (cj_…). |
name | string | yes | A name of yours (daily-report). Allowed: at least 1 character, at most 64 characters. |
schedule | string | { everyMinutes } | yes | When it runs: a 5-field cron expression ("0 8 * * *" = 08:00 every day, "*/15 * * * *" = every 15 minutes) or { everyMinutes: n }. The plan sets the shortest interval. |
schedule.everyMinutes | number | yes | Run every this many minutes. Allowed: > 0. |
request | { method, url, headers?, body?, timeoutMs? } | yes | The HTTP call each run makes. |
request.method | 'GET' | 'POST' | yes | GET or POST. |
request.url | string | yes | A URL on the project's own https:// host (the published site for live, the preview for dev). Allowed: a URL. |
request.headers | Record<string, string> | no | Extra headers to send. |
request.body | string | no | The body of a POST. Allowed: at most 65536 characters. |
request.timeoutMs | number | no | How long a run may take. Default 30 s, at most 30 s. Allowed: > 0, ≤ 30000. |
enabled | boolean | yes | false creates it paused. Default true. |
status | 'active' | 'paused' | 'paused_failures' | yes | active, paused (by you) or paused_failures (after too many failed runs; fix the route and resume). |
nextRunAt | string | null | yes | When it runs next, or null while paused. |
createdAt | string | yes | When it was created. |
env | 'dev' | 'live' | yes | live (the published site) or dev (the preview). Default: the environment of request.url. |
pauseAfterFailures | number | null | yes | Failed runs in a row before it pauses; null = never. Allowed: ≥ 0, ≤ 100. |
lastRun | { at, status, latencyMs } | no | The latest run. |
lastRun.at | string | yes | When it ran. |
lastRun.status | number | 'timeout' | 'error' | 'skipped' | yes | The HTTP status your route answered, or timeout, error (no answer) or skipped (cron was switched off). |
lastRun.latencyMs | number | yes | How long it took. |
description | string | no | A note of yours. |
timezone | string | no | An IANA time zone (Europe/Madrid): the schedule reads that zone's clock, daylight saving included. Default UTC. Allowed: at least 1 character, at most 64 characters. |
Errors — besides the errors every call can throw:
| Code | HTTP | When |
|---|---|---|
CRON_JOB_NOT_FOUND | 404 | No job with this id. |
INVALID_SCHEDULE | 400 | The new schedule is invalid or too frequent for the plan. |
CRON_URL_NOT_ALLOWED | 403 | The new URL is not the project's own host. |
Example
const job = await totalum.cron.update('cj_01M4P1F0R7T2Y9U4I6O3P8A5SD', { schedule: { everyMinutes: 60 } });Result:
{ "id": "cj_01M4P1F0R7T2Y9U4I6O3P8A5SD", "name": "daily-report", "schedule": { "everyMinutes": 60 }, "status": "active", "nextRunAt": "2026-10-11T19:30:00.000Z", … }#cron.delete
cron.delete(id: string): Promise<void>Deletes a job and its run history.
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
id | string | yes | The job's id. |
Returns Promise<void> — Nothing once deleted.
Errors — besides the errors every call can throw:
| Code | HTTP | When |
|---|---|---|
CRON_JOB_NOT_FOUND | 404 | No job with this id. |
Example
await totalum.cron.delete('cj_01M4P1F0R7T2Y9U4I6O3P8A5SD');#cron.pause
cron.pause(id: string): Promise<CronJob>Stops a job from firing until resume (the same as update(id, { enabled: false })).
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
id | string | yes | The job's id. |
Returns Promise<CronJob> — The job, now paused.
| Field | Type | Always present | Description |
|---|---|---|---|
id | string | yes | The job id (cj_…). |
name | string | yes | A name of yours (daily-report). Allowed: at least 1 character, at most 64 characters. |
schedule | string | { everyMinutes } | yes | When it runs: a 5-field cron expression ("0 8 * * *" = 08:00 every day, "*/15 * * * *" = every 15 minutes) or { everyMinutes: n }. The plan sets the shortest interval. |
schedule.everyMinutes | number | yes | Run every this many minutes. Allowed: > 0. |
request | { method, url, headers?, body?, timeoutMs? } | yes | The HTTP call each run makes. |
request.method | 'GET' | 'POST' | yes | GET or POST. |
request.url | string | yes | A URL on the project's own https:// host (the published site for live, the preview for dev). Allowed: a URL. |
request.headers | Record<string, string> | no | Extra headers to send. |
request.body | string | no | The body of a POST. Allowed: at most 65536 characters. |
request.timeoutMs | number | no | How long a run may take. Default 30 s, at most 30 s. Allowed: > 0, ≤ 30000. |
enabled | boolean | yes | false creates it paused. Default true. |
status | 'active' | 'paused' | 'paused_failures' | yes | active, paused (by you) or paused_failures (after too many failed runs; fix the route and resume). |
nextRunAt | string | null | yes | When it runs next, or null while paused. |
createdAt | string | yes | When it was created. |
env | 'dev' | 'live' | yes | live (the published site) or dev (the preview). Default: the environment of request.url. |
pauseAfterFailures | number | null | yes | Failed runs in a row before it pauses; null = never. Allowed: ≥ 0, ≤ 100. |
lastRun | { at, status, latencyMs } | no | The latest run. |
lastRun.at | string | yes | When it ran. |
lastRun.status | number | 'timeout' | 'error' | 'skipped' | yes | The HTTP status your route answered, or timeout, error (no answer) or skipped (cron was switched off). |
lastRun.latencyMs | number | yes | How long it took. |
description | string | no | A note of yours. |
timezone | string | no | An IANA time zone (Europe/Madrid): the schedule reads that zone's clock, daylight saving included. Default UTC. Allowed: at least 1 character, at most 64 characters. |
Errors — besides the errors every call can throw:
| Code | HTTP | When |
|---|---|---|
CRON_JOB_NOT_FOUND | 404 | No job with this id. |
Example
const job = await totalum.cron.pause('cj_01M4P1F0R7T2Y9U4I6O3P8A5SD');Result:
{ "id": "cj_01M4P1F0R7T2Y9U4I6O3P8A5SD", "enabled": false, "status": "paused", "nextRunAt": null, … }#cron.resume
cron.resume(id: string): Promise<CronJob>Lets a paused job fire again — also one paused after failing runs (paused_failures) once its route is fixed.
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
id | string | yes | The job's id. |
Returns Promise<CronJob> — The job, now active.
| Field | Type | Always present | Description |
|---|---|---|---|
id | string | yes | The job id (cj_…). |
name | string | yes | A name of yours (daily-report). Allowed: at least 1 character, at most 64 characters. |
schedule | string | { everyMinutes } | yes | When it runs: a 5-field cron expression ("0 8 * * *" = 08:00 every day, "*/15 * * * *" = every 15 minutes) or { everyMinutes: n }. The plan sets the shortest interval. |
schedule.everyMinutes | number | yes | Run every this many minutes. Allowed: > 0. |
request | { method, url, headers?, body?, timeoutMs? } | yes | The HTTP call each run makes. |
request.method | 'GET' | 'POST' | yes | GET or POST. |
request.url | string | yes | A URL on the project's own https:// host (the published site for live, the preview for dev). Allowed: a URL. |
request.headers | Record<string, string> | no | Extra headers to send. |
request.body | string | no | The body of a POST. Allowed: at most 65536 characters. |
request.timeoutMs | number | no | How long a run may take. Default 30 s, at most 30 s. Allowed: > 0, ≤ 30000. |
enabled | boolean | yes | false creates it paused. Default true. |
status | 'active' | 'paused' | 'paused_failures' | yes | active, paused (by you) or paused_failures (after too many failed runs; fix the route and resume). |
nextRunAt | string | null | yes | When it runs next, or null while paused. |
createdAt | string | yes | When it was created. |
env | 'dev' | 'live' | yes | live (the published site) or dev (the preview). Default: the environment of request.url. |
pauseAfterFailures | number | null | yes | Failed runs in a row before it pauses; null = never. Allowed: ≥ 0, ≤ 100. |
lastRun | { at, status, latencyMs } | no | The latest run. |
lastRun.at | string | yes | When it ran. |
lastRun.status | number | 'timeout' | 'error' | 'skipped' | yes | The HTTP status your route answered, or timeout, error (no answer) or skipped (cron was switched off). |
lastRun.latencyMs | number | yes | How long it took. |
description | string | no | A note of yours. |
timezone | string | no | An IANA time zone (Europe/Madrid): the schedule reads that zone's clock, daylight saving included. Default UTC. Allowed: at least 1 character, at most 64 characters. |
Errors — besides the errors every call can throw:
| Code | HTTP | When |
|---|---|---|
CRON_JOB_NOT_FOUND | 404 | No job with this id. |
Example
const job = await totalum.cron.resume('cj_01M4P1F0R7T2Y9U4I6O3P8A5SD');Result:
{ "id": "cj_01M4P1F0R7T2Y9U4I6O3P8A5SD", "enabled": true, "status": "active", "nextRunAt": "2026-10-12T06:00:00.000Z", … }#cron.runs
cron.runs(id: string, opts?: { limit?, cursor? }): Promise<CronRunsPage>A job's executions of the last 30 days, newest first: when each ran, the HTTP status your route answered and how long it took. Free.
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
id | string | yes | The job's id. |
opts | { limit?, cursor? } | no | Paging. |
opts.limit | number | no | Runs per page. |
opts.cursor | string | no | The previous page's nextCursor. |
Returns Promise<CronRunsPage> — One page of runs.
| Field | Type | Always present | Description |
|---|---|---|---|
items | CronRun[] | yes | The runs, newest first. |
nextCursor | string | null | yes | Pass it as cursor for the next page; null on the last. |
Errors — besides the errors every call can throw:
| Code | HTTP | When |
|---|---|---|
CRON_JOB_NOT_FOUND | 404 | No job with this id. |
Example
const page = await totalum.cron.runs('cj_01M4P1F0R7T2Y9U4I6O3P8A5SD', { limit: 2 });Result:
{
"items": [
{ "id": "cr_01M4P1G2H3J4K5L6M7N8P9Q0RS", "scheduledFor": "2026-10-11T06:00:00.000Z", "startedAt": "2026-10-11T06:00:00.412Z", "status": 200, "latencyMs": 812, "responseSnippet": "{\"ok\":true}" },
{ "id": "cr_01M4MZ8B7V6C5X4Z3A2S1D0F9G", "scheduledFor": "2026-10-10T06:00:00.000Z", "startedAt": "2026-10-10T06:00:00.388Z", "status": "timeout", "latencyMs": 30000, "error": "The request timed out" }
],
"nextCursor": "MjAyNi0xMC0xMFQwNjowMDowMC4wMDBa"
}#cron.trigger
cron.trigger(id: string): Promise<{ runId }>Fires a job now, outside its schedule — a "Run now" button, or to test a new job. At most 10 manual runs a minute per project.
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
id | string | yes | The job's id. |
Returns Promise<{ runId }> — The id of the run it started (it shows in runs() once done).
| Field | Type | Always present | Description |
|---|---|---|---|
runId | string | yes | The id of the run that was started. |
Errors — besides the errors every call can throw:
| Code | HTTP | When |
|---|---|---|
CRON_JOB_NOT_FOUND | 404 | No job with this id. |
RATE_LIMITED | 429 | More than 10 manual runs in a minute; details.retryAfterSeconds. |
Example
const { runId } = await totalum.cron.trigger('cj_01M4P1F0R7T2Y9U4I6O3P8A5SD');Result:
{ "runId": "cr_01M4P1H5J6K7L8M9N0P1Q2R3ST" }#CronJob
A scheduled job.
| Field | Type | Always present | Description |
|---|---|---|---|
id | string | yes | The job id (cj_…). |
name | string | yes | A name of yours (daily-report). Allowed: at least 1 character, at most 64 characters. |
schedule | string | { everyMinutes } | yes | When it runs: a 5-field cron expression ("0 8 * * *" = 08:00 every day, "*/15 * * * *" = every 15 minutes) or { everyMinutes: n }. The plan sets the shortest interval. |
schedule.everyMinutes | number | yes | Run every this many minutes. Allowed: > 0. |
request | { method, url, headers?, body?, timeoutMs? } | yes | The HTTP call each run makes. |
request.method | 'GET' | 'POST' | yes | GET or POST. |
request.url | string | yes | A URL on the project's own https:// host (the published site for live, the preview for dev). Allowed: a URL. |
request.headers | Record<string, string> | no | Extra headers to send. |
request.body | string | no | The body of a POST. Allowed: at most 65536 characters. |
request.timeoutMs | number | no | How long a run may take. Default 30 s, at most 30 s. Allowed: > 0, ≤ 30000. |
enabled | boolean | yes | false creates it paused. Default true. |
status | 'active' | 'paused' | 'paused_failures' | yes | active, paused (by you) or paused_failures (after too many failed runs; fix the route and resume). |
nextRunAt | string | null | yes | When it runs next, or null while paused. |
createdAt | string | yes | When it was created. |
env | 'dev' | 'live' | yes | live (the published site) or dev (the preview). Default: the environment of request.url. |
pauseAfterFailures | number | null | yes | Failed runs in a row before it pauses; null = never. Allowed: ≥ 0, ≤ 100. |
lastRun | { at, status, latencyMs } | no | The latest run. |
lastRun.at | string | yes | When it ran. |
lastRun.status | number | 'timeout' | 'error' | 'skipped' | yes | The HTTP status your route answered, or timeout, error (no answer) or skipped (cron was switched off). |
lastRun.latencyMs | number | yes | How long it took. |
description | string | no | A note of yours. |
timezone | string | no | An IANA time zone (Europe/Madrid): the schedule reads that zone's clock, daylight saving included. Default UTC. Allowed: at least 1 character, at most 64 characters. |
#CronJobInput
A job for cron.create().
| Name | Type | Required | Description |
|---|---|---|---|
name | string | yes | A name of yours (daily-report). Allowed: at least 1 character, at most 64 characters. |
schedule | string | { everyMinutes } | yes | When it runs: a 5-field cron expression ("0 8 * * *" = 08:00 every day, "*/15 * * * *" = every 15 minutes) or { everyMinutes: n }. The plan sets the shortest interval. |
schedule.everyMinutes | number | yes | Run every this many minutes. Allowed: > 0. |
request | { method, url, headers?, body?, timeoutMs? } | yes | The HTTP call each run makes. |
request.method | 'GET' | 'POST' | yes | GET or POST. |
request.url | string | yes | A URL on the project's own https:// host (the published site for live, the preview for dev). Allowed: a URL. |
request.headers | Record<string, string> | no | Extra headers to send. |
request.body | string | no | The body of a POST. Allowed: at most 65536 characters. |
request.timeoutMs | number | no | How long a run may take. Default 30 s, at most 30 s. Allowed: > 0, ≤ 30000. |
enabled | boolean | no | false creates it paused. Default true. |
description | string | no | A note of yours. |
env | 'dev' | 'live' | no | live (the published site) or dev (the preview). Default: the environment of request.url. |
timezone | string | no | An IANA time zone (Europe/Madrid): the schedule reads that zone's clock, daylight saving included. Default UTC. Allowed: at least 1 character, at most 64 characters. |
pauseAfterFailures | number | null | no | Pause the job after this many failed runs in a row. Default 3; null or 0 never pauses. Allowed: ≥ 0, ≤ 100. |
#CronJobPatch
The fields cron.update() changes; each is optional and means the same as in cron.create().
| Name | Type | Required | Description |
|---|---|---|---|
name | string | no | A name of yours (daily-report). Allowed: at least 1 character, at most 64 characters. |
schedule | string | { everyMinutes } | no | When it runs: a 5-field cron expression ("0 8 * * *" = 08:00 every day, "*/15 * * * *" = every 15 minutes) or { everyMinutes: n }. The plan sets the shortest interval. |
schedule.everyMinutes | number | yes | Run every this many minutes. Allowed: > 0. |
request | { method, url, headers?, body?, timeoutMs? } | no | The HTTP call each run makes. |
request.method | 'GET' | 'POST' | yes | GET or POST. |
request.url | string | yes | A URL on the project's own https:// host (the published site for live, the preview for dev). Allowed: a URL. |
request.headers | Record<string, string> | no | Extra headers to send. |
request.body | string | no | The body of a POST. Allowed: at most 65536 characters. |
request.timeoutMs | number | no | How long a run may take. Default 30 s, at most 30 s. Allowed: > 0, ≤ 30000. |
enabled | boolean | no | false creates it paused. Default true. |
description | string | no | A note of yours. |
env | 'dev' | 'live' | no | live (the published site) or dev (the preview). Default: the environment of request.url. |
timezone | string | no | An IANA time zone (Europe/Madrid): the schedule reads that zone's clock, daylight saving included. Default UTC. Allowed: at least 1 character, at most 64 characters. |
pauseAfterFailures | number | null | no | Pause the job after this many failed runs in a row. Default 3; null or 0 never pauses. Allowed: ≥ 0, ≤ 100. |
#CronRun
One execution of a job.
| Field | Type | Always present | Description |
|---|---|---|---|
id | string | yes | The run id (cr_…). |
scheduledFor | string | yes | When it was due. |
startedAt | string | null | yes | When the call started, or null if it never did. |
status | number | 'timeout' | 'error' | 'skipped' | yes | The HTTP status your route answered, or timeout, error or skipped. |
latencyMs | number | null | yes | How long the call took, or null. |
error | string | no | Why it failed, when it did. |
responseSnippet | string | no | The first 1 KB of your route's answer. |
#CronRunsPage
One page of cron.runs().
| Field | Type | Always present | Description |
|---|---|---|---|
items | CronRun[] | yes | The runs, newest first. |
nextCursor | string | null | yes | Pass it as cursor for the next page; null on the last. |
