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

POST/api/v1/cron/jobs cria um jobcreates a job
GET/api/v1/cron/jobs lista seus jobslists your jobs
GET/api/v1/cron/jobs/{id} detalhe de um joba single job's detail
PUT/api/v1/cron/jobs/{id} atualiza um jobupdates a job
DELETE/api/v1/cron/jobs/{id} remove um jobdeletes a job
POST/api/v1/cron/jobs/{id}/trigger força uma execução imediataforces an immediate run
GET/api/v1/cron/worker/status status do worker de execuçãoexecution worker's status
POST/api/v1/cron/worker/stop pausa o workerpauses the worker
POST/api/v1/cron/worker/start retoma o workerresumes the worker

Campos do job

Job fields

CampoFieldDescriçãoDescription
namenome do jobthe job's name
scheduleexpressã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_sourcenome da imagem, ou a URL do repositório Gitthe image name, or the Git repo URL
commandopcional — sobrescreve o entrypoint da imagemoptional — overrides the image's entrypoint
env_varsopcional — variáveis de ambiente do containeroptional — the container's environment variables
cpu_limit / memory_limitopcional — limites de recurso do containeroptional — the container's resource limits
timeout_sectempo máximo de execução antes de matar o containermax 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_concurrentse permite uma execução nova começar antes da anterior terminarwhether 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

StatusMotivoReason
400campos obrigatórios ausentes, image_type inválido, ou schedule mal formadomissing required fields, invalid image_type, or malformed schedule
401token ausente ou inválidomissing or invalid token
404job não encontrado, ou não pertence a vocêjob not found, or it isn't yours
429limite de taxa excedido — cada operação (create, list, trigger...) tem cota própriarate 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.