CRON
Jobs agendados
Agende tarefas recorrentes que rodam isoladas em containers Docker — sua própria imagem, ou um repositório Git que a gente builda. Você define o quê e quando; a execução acontece fora da chamada que criou o job.
Scheduled jobs
Schedule recurring tasks that run isolated in Docker containers — your own image, or a Git repo we build for you. You define what and when; execution happens outside the call that created the job.
ASYNC a resposta confirma, não executa the response confirms, it doesn't run the job
Por que é assíncrona
Why it's async
Nas outras APIs, a resposta HTTP é o resultado: você pergunta o endereço de um CEP, a resposta já é o endereço. Aqui não — quando você faz POST /api/v1/cron/jobs, a resposta é só a confirmação de que o job foi cadastrado, com um id e um next_run_at calculado a partir do schedule. O trabalho em si (buildar a imagem se for um repo Git, subir o container, rodar o comando) acontece depois, de forma independente, num worker separado que varre os jobs prontos pra rodar. Pra saber o que aconteceu numa execução, você consulta o job de volta (GET) ou olha o status do worker — a criação não devolve output nenhum, porque nada rodou ainda.
In the other APIs, the HTTP response is the result: you ask for a CEP's address, the response already is the address. Not here — when you POST /api/v1/cron/jobs, the response is just confirmation that the job was registered, with an id and a next_run_at computed from the schedule. The actual work (building the image if it's a Git repo, starting the container, running the command) happens later, independently, in a separate worker that scans for jobs ready to run. To find out what happened in a run, you query the job back (GET) or check the worker's status — creation returns no output, because nothing has run yet.
Endpoints
Endpoints
/api/v1/cron/jobs
cria um jobcreates a job
/api/v1/cron/jobs
lista seus jobslists your jobs
/api/v1/cron/jobs/{id}
detalhe de um joba single job's detail
/api/v1/cron/jobs/{id}
atualiza um jobupdates a job
/api/v1/cron/jobs/{id}
remove um jobdeletes a job
/api/v1/cron/jobs/{id}/trigger
força uma execução imediataforces an immediate run
/api/v1/cron/worker/status
status do worker de execuçãoexecution worker's status
/api/v1/cron/worker/stop
pausa o workerpauses the worker
/api/v1/cron/worker/start
retoma o workerresumes the worker
Campos do job
Job fields
| Campo | Field | Descrição | Description |
|---|---|---|---|
name | nome do job | the job's name | |
schedule | expressão cron ("0 3 * * *" = todo dia às 3h) | a cron expression ("0 3 * * *" = every day at 3am) | |
image_type | "image" (imagem Docker pronta) ou "git" (repositório — buildamos por você) | "image" (ready-made Docker image) or "git" (a repo — we build it for you) | |
image_source | nome da imagem, ou a URL do repositório Git | the image name, or the Git repo URL | |
command | opcional — sobrescreve o entrypoint da imagem | optional — overrides the image's entrypoint | |
env_vars | opcional — variáveis de ambiente do container | optional — the container's environment variables | |
cpu_limit / memory_limit | opcional — limites de recurso do container | optional — the container's resource limits | |
timeout_sec | tempo máximo de execução antes de matar o container | max run time before the container gets killed | |
missed_runs | "skip" (padrão) ou "run_once" — o que fazer se o worker ficou fora do ar na hora agendada | "skip" (default) or "run_once" — what to do if the worker was down at the scheduled time | |
allow_concurrent | se permite uma execução nova começar antes da anterior terminar | whether a new run can start before the previous one finishes |
Exemplo
Example
# criar — devolve o job com id, não o resultado de rodar nada# create — returns the job with an id, not the result of running anything
curl -X POST https://cron.alicercelabs.com.br/api/v1/cron/jobs \
-H "Authorization: Bearer <token>" \
-d '{
"name": "relatorio-diario",
"schedule": "0 3 * * *",
"image_type": "image",
"image_source": "meurepo/relatorio:latest",
"timeout_sec": 600
}'
{
"success": true,
"data": {
"id": "8f1c...",
"name": "relatorio-diario",
"schedule": "0 3 * * *",
"image_type": "image",
"image_source": "meurepo/relatorio:latest",
"missed_runs": "skip",
"allow_concurrent": false,
"active": true,
"last_run_at": null,
"next_run_at": "2026-08-20T03:00:00Z",
"created_at": "2026-08-19T18:00:00Z"
},
"meta": { "elapsed_ms": 9, "request_id": "..." }
}
Repare em last_run_at: null — o job existe, mas ainda não rodou. Pra forçar uma execução sem esperar o schedule, use POST /jobs/{id}/trigger; pra ver o que aconteceu depois, consulte GET /jobs/{id} de novo e olhe last_run_at.
Note last_run_at: null — the job exists, but hasn't run yet. To force a run without waiting for the schedule, use POST /jobs/{id}/trigger; to see what happened afterward, query GET /jobs/{id} again and check last_run_at.
Erros possíveis
Possible errors
| Status | Motivo | Reason |
|---|---|---|
| 400 | campos obrigatórios ausentes, image_type inválido, ou schedule mal formado | missing required fields, invalid image_type, or malformed schedule |
| 401 | token ausente ou inválido | missing or invalid token |
| 404 | job não encontrado, ou não pertence a você | job not found, or it isn't yours |
| 429 | limite de taxa excedido — cada operação (create, list, trigger...) tem cota própria | rate limit exceeded — each operation (create, list, trigger...) has its own quota |
Limites
Limits
10.000/dia · 416/hora por operação — create, list, get, update, delete, trigger e os três endpoints de worker/ contam separado. Um script que só lista jobs não come a cota de quem está criando.
10,000/day · 416/hour per operation — create, list, get, update, delete, trigger and the three worker/ endpoints are counted separately. A script that only lists jobs doesn't eat into the quota of whoever is creating them.