Monitor GitHub Actions Cron Workflows with Crontiq
GitHub Actions supports schedule triggers that run workflows on a cron expression. The problem: when these workflows fail, GitHub sends no notification by default. Worse, GitHub may silently disable scheduled workflows on inactive repositories after 60 days. You need an external watchdog.
Crontiq monitors your scheduled GitHub Actions workflows with a single curl call. If the workflow does not ping Crontiq within the expected window, you get an alert. If it sends JSON metrics, Crontiq detects anomalies automatically.
Basic Setup: Ping on Completion
Add one step at the end of your scheduled workflow. When the job completes successfully, it pings Crontiq. If the workflow never runs or fails before reaching the final step, Crontiq marks it as down.
# .github/workflows/nightly-sync.yml
name: Nightly Data Sync
on:
schedule:
- cron: '0 3 * * *' # Every day at 03:00 UTC
jobs:
sync:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Run sync script
run: python scripts/sync_data.py
- name: Ping Crontiq
if: success()
run: |
curl -s -o /dev/null \
https://ping.crontiq.io/p/${{ secrets.CRONTIQ_API_KEY }}/nightly-sync
Store your API key as a repository secret named CRONTIQ_API_KEY. The monitor nightly-sync is created automatically on the first ping — no dashboard setup required.
Advanced: Start, Fail, and Metrics
For longer-running workflows, signal the start of the job so Crontiq can track duration. If a step fails, report it explicitly with the /fail endpoint.
# .github/workflows/etl-pipeline.yml
name: ETL Pipeline
on:
schedule:
- cron: '30 2 * * 1-5' # Weekdays at 02:30 UTC
jobs:
etl:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Signal start
run: |
curl -s -o /dev/null \
https://ping.crontiq.io/p/${{ secrets.CRONTIQ_API_KEY }}/etl-pipeline/start
- name: Run ETL
id: etl
run: |
RESULT=$(python scripts/run_etl.py --output-json)
echo "metrics=$RESULT" >> $GITHUB_OUTPUT
- name: Report success with metrics
if: success()
run: |
curl -s -o /dev/null -X POST \
-H "Content-Type: application/json" \
-d '${{ steps.etl.outputs.metrics }}' \
https://ping.crontiq.io/p/${{ secrets.CRONTIQ_API_KEY }}/etl-pipeline
- name: Report failure
if: failure()
run: |
curl -s -o /dev/null \
https://ping.crontiq.io/p/${{ secrets.CRONTIQ_API_KEY }}/etl-pipeline/fail
Sending JSON Metrics
Your script can output any JSON. Crontiq flattens nested objects and extracts every numeric value as a metric. No schema definition needed.
# Example: your Python script outputs this JSON
{"rows_synced": 14302, "duration_ms": 8420, "errors": 0, "db": {"connections": 5}}
# Crontiq automatically tracks:
# rows_synced = 14302
# duration_ms = 8420
# errors = 0
# db.connections = 5
#
# If rows_synced suddenly drops from ~14000 to 200,
# Crontiq flags a WARNING via anomaly detection.
Why Not Just Use GitHub Notifications?
- GitHub disables scheduled workflows on repos with no commits for 60 days — silently.
- Failed cron jobs do not trigger email notifications unless you configure them explicitly.
- You get no visibility into trends — was the job slower than usual? Did it process fewer rows?
- Crontiq gives you a public status badge you can embed in your README.
Add a Status Badge to Your README
Every monitor gets a public token. Use it to embed a live status badge:

The badge updates in real time: green when the job is running on schedule, red when it misses a window, purple when an anomaly is detected.