Skip to main content

Cron Jobs

Define scheduled prompts in your chucky.json configuration file. When you run chucky deploy, your cron jobs are synced to Chucky’s scheduler.

Configuration

Add a crons array to your chucky.json:
{
  "crons": [
    {
      "cron": "0 9 * * 1-5",
      "timezone": "America/New_York",
      "message": "Generate daily standup summary from yesterday's git commits",
      "model": "claude-sonnet-4-5-20250929",
      "maxTurns": 5,
      "maxBudgetUsd": 0.25
    }
  ]
}

Cron Expression Format

Standard 5-field cron expressions:
┌───────────── minute (0-59)
│ ┌───────────── hour (0-23)
│ │ ┌───────────── day of month (1-31)
│ │ │ ┌───────────── month (1-12)
│ │ │ │ ┌───────────── day of week (0-6, Sun=0)
│ │ │ │ │
* * * * *

Examples

ExpressionDescription
0 9 * * *Every day at 9:00 AM
0 9 * * 1-5Weekdays at 9:00 AM
*/15 * * * *Every 15 minutes
0 0 1 * *First day of every month at midnight
0 0 * * 0Every Sunday at midnight

Full Schema

interface CronDefinition {
  // Required
  cron: string;           // Cron expression
  message: string;        // Prompt to execute

  // Scheduling
  timezone?: string;      // IANA timezone (default: "UTC")
  enabled?: boolean;      // Whether active (default: true)

  // Callback
  callback?: {
    url: string;          // Webhook URL for results
    headers?: Record<string, string>;
    secret?: string;      // HMAC signing secret
  };

  // SDK Options
  model?: string;
  maxTurns?: number;
  maxBudgetUsd?: number;
  maxThinkingTokens?: number;
  systemPrompt?: string;
  tools?: string[];
  allowedTools?: string[];
  disallowedTools?: string[];
  env?: Record<string, string>;
  outputFormat?: {
    type: "json_schema";
    schema: object;
  };
}

Deploying Crons

When you run chucky deploy, the CLI:
  1. Reads cron definitions from chucky.json
  2. Deletes any existing cron schedules for the project
  3. Creates fresh schedules for each enabled cron
chucky deploy
Output:
Deploying project: my-project

Syncing cron jobs...
  ✓ Created: 0 9 * * 1-5 (America/New_York)
  ✓ Created: 0 0 * * 0 (UTC)
  ○ Skipped (disabled): 0 12 * * * (UTC)

Synced 3 cron job(s)

Example Configurations

Daily Report with Slack Webhook

{
  "crons": [
    {
      "cron": "0 9 * * 1-5",
      "timezone": "America/New_York",
      "message": "Generate a summary of yesterday's git commits and create a standup report",
      "model": "claude-sonnet-4-5-20250929",
      "systemPrompt": "You are a DevOps assistant. Format output for Slack.",
      "maxTurns": 5,
      "maxBudgetUsd": 0.25,
      "callback": {
        "url": "https://hooks.slack.com/services/xxx/yyy/zzz"
      }
    }
  ]
}

Weekly Metrics with Structured Output

{
  "crons": [
    {
      "cron": "0 0 * * 0",
      "timezone": "UTC",
      "message": "Generate weekly metrics report for the past 7 days",
      "maxBudgetUsd": 1.00,
      "outputFormat": {
        "type": "json_schema",
        "schema": {
          "type": "object",
          "properties": {
            "summary": { "type": "string" },
            "metrics": {
              "type": "object",
              "properties": {
                "commits": { "type": "number" },
                "prs_merged": { "type": "number" },
                "issues_closed": { "type": "number" }
              }
            },
            "highlights": {
              "type": "array",
              "items": { "type": "string" }
            }
          },
          "required": ["summary", "metrics"]
        }
      },
      "callback": {
        "url": "https://api.myapp.com/webhooks/metrics",
        "headers": {
          "X-API-Key": "your-api-key"
        },
        "secret": "whsec_xxx"
      }
    }
  ]
}

Multiple Crons with Different Schedules

{
  "crons": [
    {
      "cron": "0 8 * * 1-5",
      "timezone": "Europe/London",
      "message": "Check for security vulnerabilities in dependencies",
      "maxTurns": 10,
      "maxBudgetUsd": 0.50
    },
    {
      "cron": "0 18 * * 5",
      "timezone": "Europe/London",
      "message": "Generate weekly code review summary",
      "maxBudgetUsd": 0.75
    },
    {
      "cron": "0 0 1 * *",
      "message": "Generate monthly usage report",
      "maxBudgetUsd": 1.00,
      "enabled": false
    }
  ]
}

Callback Webhooks

Results are POSTed to your callback URL when the cron completes:
{
  "success": true,
  "text": "Generated report content...",
  "result": {
    "type": "result",
    "subtype": "success",
    "total_cost_usd": 0.015
  }
}

HMAC Verification

If you provide a secret, the request includes an X-Chucky-Signature header:
const crypto = require('crypto');

function verifySignature(body, signature, secret) {
  const expected = crypto
    .createHmac('sha256', secret)
    .update(body)
    .digest('hex');
  return signature === expected;
}

// In your webhook handler
app.post('/webhook', (req, res) => {
  const signature = req.headers['x-chucky-signature'];
  const isValid = verifySignature(
    JSON.stringify(req.body),
    signature,
    'whsec_xxx'
  );

  if (!isValid) {
    return res.status(401).send('Invalid signature');
  }

  // Process the result...
});

Timezones

Use IANA timezone identifiers:
TimezoneExample Cities
UTCDefault
America/New_YorkNew York, Miami
America/Los_AngelesLos Angeles, Seattle
Europe/LondonLondon
Europe/ParisParis, Berlin
Asia/TokyoTokyo
Asia/ShanghaiShanghai, Beijing
Australia/SydneySydney

Best Practices

Always set maxBudgetUsd to prevent runaway costs. Start low and increase based on actual usage.
Don’t rely on polling. Configure webhooks to receive results immediately when crons complete.
Set enabled: false while testing your configuration, then enable when ready.
When feeding results into other systems, use outputFormat to ensure consistent JSON structure.

Viewing Cron Status

View your cron jobs in the Chucky Dashboard:
  • Next run time - When the cron will next execute
  • Last run status - Success/failure of the most recent run
  • Run history - Past executions with results

Concurrency

Cron jobs share the same concurrency limits as the Incubate API:
TierConcurrent Tasks
Hobby/Free2
Starter5
Pro10
If your cron triggers while at capacity, it will queue and execute when a slot becomes available.