FacturIQ

How to run Claude Code, or any AI agent, on a cron schedule

An agent only runs when something calls it. To make one run on a schedule you need a clock outside the agent: a local crontab, a CI scheduler like GitHub Actions, a cloud cron, or a hosted service that calls your endpoint. The choice comes down to one question: what happens when your laptop is closed?

The four ways, compared

MethodRuns when your machine is off?SetupTells you a run was missed?Cost
Local crontab / launchdNoOne line in crontab -eNo. A missed run leaves no trace at all.Free
GitHub Actions scheduleYesA workflow file and repository secretsPartly: you see runs that started, not windows the scheduler skipped.Free on public repos
Cloud cron
Cloudflare, Lambda, Cloud Scheduler
YesDeploy something that holds your keysOnly if you build the logging yourself.Cents to a few dollars
Hosted wake service
what FacturIQ does
YesOne API call; no infrastructureYes. Every attempt is a row, including the ones that never fired.Free for one daily wake

The simple case: a local crontab

If the work is yours alone and the machine is always on, this is genuinely enough. Claude Code runs non-interactively with -p, so a cron line is all it takes:

# every weekday at 09:00, run one prompt and log the output
0 9 * * 1-5 cd ~/project && /usr/local/bin/claude -p "Review yesterday's commits and write notes to notes.md" >> ~/agent.log 2>&1

Two things to know before you rely on it. Cron runs with a minimal environment, so absolute paths and an explicit PATH matter. And on macOS the machine sleeping means the job does not run; launchd with StartCalendarInterval will catch up after a wake, plain cron will not.

The problem with all of them: silence

Every scheduler above is good at starting a job. None of them, by default, is good at telling you a job did not start. A crontab that stops firing looks exactly like a crontab with nothing to do. The agent does not report the runs it never had, because it was not running.

This is the failure mode that actually costs people work: not a crash, which is loud, but an absence, which is quiet. If a scheduled agent matters, the scheduler needs to record every window, including the empty ones.

A gap in a log has exactly one honest meaning: the scheduler did not run. That is only useful if every attempt writes a line, successes and failures alike.

A wake with a receipt

FacturIQ schedules a signed HTTPS call to an endpoint the agent controls and writes a row for every attempt. Create one with a five-field UTC cron expression:

curl -s -X POST https://api.facturiq.com/v1/wakes \
  -H "authorization: Bearer $FACTURIQ_KEY" -H 'content-type: application/json' \
  -d '{"cron":"0 */6 * * *","webhook_url":"https://your-endpoint.example/wake"}'

Before anything is delivered, the endpoint has to prove it belongs to the agent: FacturIQ posts a challenge and the endpoint answers with a signature made by the agent's own key. After that, each delivery carries an HMAC signature and an Ed25519 signature from the registry, so the receiver can tell a real wake from anything else that finds the URL.

Failures retry after 1, 5 and 25 minutes. Ten consecutive failures disable the schedule and email the operator, rather than retrying into the void. Every attempt, retry, skip and miss is readable:

curl -s https://api.facturiq.com/v1/wakes/12/runs -H "authorization: Bearer $FACTURIQ_KEY"
# {"runs":[{"outcome":"delivered","http_status":200,"duration_ms":142,...},
#          {"outcome":"failed:timeout","attempt":1,...},
#          {"outcome":"missed","scheduled_for":...}]}

If you would rather not run the agent yourself

On the Pro plan FacturIQ can execute the agent instead of calling you: it holds your own Anthropic API key encrypted, runs a short tool loop on the schedule, and records tokens, estimated cost and a summary per run. The model bill goes to your key, not through us. The tool surface is deliberately small, and network access is limited to origins you list, because a scheduled agent reading the open web is a prompt-injection surface.

Which to choose

Use a local crontab when the machine is always on and nobody but you depends on the result. Use GitHub Actions when the work is already in a repository and its secrets belong there. Use a hosted wake when the agent must return whether or not your laptop is open, and when a missed run is something you need to find out about rather than discover weeks later.

Questions people ask

Can Claude Code run on a schedule?

Yes. Claude Code runs non-interactively with the -p flag, so any scheduler can call it: a local crontab line, a launchd job, a GitHub Actions workflow, or a hosted service that calls a webhook on your machine. Claude Code itself has no built-in cloud scheduler.

How do I create a cron job for an AI agent?

Pick a clock outside the agent. Locally: add a line to crontab with absolute paths. In CI: a schedule trigger in a workflow file. Hosted: POST a five-field UTC cron expression and an HTTPS endpoint to a wake service, which then calls your agent on time.

What happens when a scheduled agent run is missed?

With a plain crontab, nothing: the missed run leaves no trace, which is why silent failures go unnoticed for weeks. FacturIQ writes a row for every scheduled window, including outcomes like missed, skipped and failed, so a gap is visible instead of invisible.

Why does my cron job work manually but not on a schedule?

Almost always the environment. Cron runs with a minimal PATH and no shell profile, so commands found in your terminal are not found by cron. Use absolute paths to every binary, set PATH explicitly at the top of the crontab, and redirect output to a log file to see the error.

Is there a free way to schedule an AI agent in the cloud?

Yes. GitHub Actions schedules are free on public repositories, and FacturIQ's free plan includes one scheduled wake per day with a full delivery log, no card required. Both survive your laptop being closed.

Try it on one agent, free

One agent, a daily wake, 25 MB of sealed memory and a public record cost nothing and need no card. Your agent connects with one API call.

Create an operator account Read the API