skills/automation/SKILL.md
This skill should be used when the user asks to "create an automation", "schedule a task", "set up a cron job", or mentions automations, scheduled tasks, or cron scheduling in OpenHands Cloud.
npx skillsauth add openhands/skills automationInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Create and manage scheduled tasks that run in OpenHands Cloud sandboxes on a cron schedule.
⚠️ CRITICAL — Agent behavior rules:
- ALWAYS use preset endpoints to create automations. They handle all SDK boilerplate, tarball packaging, and upload automatically:
- Prompt preset (
POST /v1/preset/prompt) — for simple tasks with a natural language prompt- Plugin preset (
POST /v1/preset/plugin) — when plugins with skills, MCP configs, or commands are needed- NEVER write custom SDK scripts or create tarballs. Do not generate Python SDK code,
setup.shfiles, or tarball uploads unless the user explicitly asks for it.- If neither preset can satisfy the requirement, do NOT silently fall back to custom automation. Instead, explain the available options to the user:
- Prompt preset — simple natural language prompt execution
- Plugin preset — load plugins with extended capabilities (skills, MCP, hooks, commands)
- Custom SDK script — full control over code; point them to
references/custom-automation.md- Let the user choose which approach to use.
- Only create custom SDK scripts if the user explicitly requests it. Refer to
references/custom-automation.mdfor the full reference.
All requests require Bearer authentication:
-H "Authorization: Bearer ${OPENHANDS_API_KEY}"
Production host: app.all-hands.dev
| Endpoint | Method | Description |
|----------|--------|-------------|
| /api/automation/v1/preset/prompt | POST | Create automation from a prompt (recommended) |
| /api/automation/v1/preset/plugin | POST | Create automation with plugins |
| /api/automation/v1 | GET | List automations |
| /api/automation/v1/{id} | GET | Get automation details |
| /api/automation/v1/{id} | PATCH | Update automation |
| /api/automation/v1/{id} | DELETE | Delete automation |
| /api/automation/v1/{id}/dispatch | POST | Trigger a run manually |
| /api/automation/v1/{id}/runs | GET | List automation runs |
Two preset endpoints simplify automation creation by handling SDK boilerplate, tarball packaging, and upload automatically:
Use the preset/prompt endpoint for simple automations. Provide a natural language prompt describing the task.
curl -X POST "https://app.all-hands.dev/api/automation/v1/preset/prompt" \
-H "Authorization: Bearer ${OPENHANDS_API_KEY}" \
-H "Content-Type: application/json" \
-d '{
"name": "My Automation Name",
"prompt": "What the automation should do",
"trigger": {
"type": "cron",
"schedule": "0 9 * * *",
"timezone": "UTC"
}
}'
| Field | Required | Description |
|-------|----------|-------------|
| name | Yes | Name of the automation (1-500 characters) |
| prompt | Yes | Natural language instructions (1-50,000 characters) |
| trigger.type | Yes | Must be "cron" |
| trigger.schedule | Yes | Cron expression (5 fields: min hour day month weekday) |
| trigger.timezone | No | IANA timezone (default: "UTC") |
| timeout | No | Max execution time in seconds (default: system maximum) |
Write the prompt as an instruction to an AI agent. The prompt executes inside a sandbox with full tool access (bash, file editing, etc.), the user's configured LLM, stored secrets, and MCP server integrations. Examples:
"Generate a weekly status report summarizing the team's GitHub activity and post it to Slack""Check the production API health endpoint every hour and alert if it returns non-200""Pull the latest data from our analytics API and update the dashboard spreadsheet"| Field | Values | Description | |-------|--------|-------------| | Minute | 0-59 | Minute of the hour | | Hour | 0-23 | Hour of the day (24-hour) | | Day | 1-31 | Day of the month | | Month | 1-12 | Month of the year | | Weekday | 0-6 | Day of week (0=Sun, 6=Sat) |
Common schedules: 0 9 * * * (daily 9 AM), 0 9 * * 1-5 (weekdays 9 AM), 0 9 * * 1 (Mondays 9 AM), 0 0 1 * * (first of month), */15 * * * * (every 15 min), 0 */6 * * * (every 6 hours).
{
"id": "123e4567-e89b-12d3-a456-426614174000",
"name": "My Automation Name",
"trigger": {"type": "cron", "schedule": "0 9 * * *", "timezone": "UTC"},
"enabled": true,
"created_at": "2025-03-25T10:00:00Z"
}
Daily report:
curl -X POST "https://app.all-hands.dev/api/automation/v1/preset/prompt" \
-H "Authorization: Bearer ${OPENHANDS_API_KEY}" \
-H "Content-Type: application/json" \
-d '{
"name": "Daily Report",
"prompt": "Generate a daily status report and save it to a file in the workspace",
"trigger": {"type": "cron", "schedule": "0 9 * * 1-5", "timezone": "America/New_York"}
}'
Weekly cleanup:
curl -X POST "https://app.all-hands.dev/api/automation/v1/preset/prompt" \
-H "Authorization: Bearer ${OPENHANDS_API_KEY}" \
-H "Content-Type: application/json" \
-d '{
"name": "Weekly Cleanup",
"prompt": "Clean up temporary files older than 7 days and send a summary of what was removed",
"trigger": {"type": "cron", "schedule": "0 2 * * 0", "timezone": "UTC"},
"timeout": 300
}'
Use the preset/plugin endpoint when you need to load one or more plugins that provide extended capabilities like skills, MCP configurations, hooks, and commands.
💡 Finding plugins: Browse the OpenHands/extensions repository for available skills and plugins. When given a broad use case, check this directory first to see if something already exists that fits your needs.
/plugin-name:command)curl -X POST "https://app.all-hands.dev/api/automation/v1/preset/plugin" \
-H "Authorization: Bearer ${OPENHANDS_API_KEY}" \
-H "Content-Type: application/json" \
-d '{
"name": "My Plugin Automation",
"plugins": [
{"source": "github:owner/repo", "ref": "v1.0.0"},
{"source": "github:owner/another-plugin"}
],
"prompt": "Use the plugin commands to perform the task",
"trigger": {
"type": "cron",
"schedule": "0 9 * * 1",
"timezone": "UTC"
}
}'
| Field | Required | Description |
|-------|----------|-------------|
| name | Yes | Name of the automation (1-500 characters) |
| plugins | Yes | List of plugin sources (at least one required) |
| plugins[].source | Yes | Plugin source: github:owner/repo, git URL, or local path |
| plugins[].ref | No | Git ref: branch, tag, or commit SHA |
| plugins[].repo_path | No | Subdirectory path for monorepos |
| prompt | Yes | Instructions for the automation (1-50,000 characters) |
| trigger.type | Yes | Must be "cron" |
| trigger.schedule | Yes | Cron expression (5 fields: min hour day month weekday) |
| trigger.timezone | No | IANA timezone (default: "UTC") |
| timeout | No | Max execution time in seconds (default: system maximum) |
| Format | Example | Description |
|--------|---------|-------------|
| GitHub shorthand | github:owner/repo | Fetches from GitHub |
| Git URL | https://github.com/owner/repo.git | Any git repository |
| With ref | {"source": "github:owner/repo", "ref": "v1.0.0"} | Specific branch/tag/commit |
| Monorepo | {"source": "github:org/monorepo", "repo_path": "plugins/my-plugin"} | Subdirectory in repo |
{
"id": "123e4567-e89b-12d3-a456-426614174000",
"name": "My Plugin Automation",
"trigger": {"type": "cron", "schedule": "0 9 * * 1", "timezone": "UTC"},
"enabled": true,
"created_at": "2025-03-25T10:00:00Z"
}
Single plugin with version:
curl -X POST "https://app.all-hands.dev/api/automation/v1/preset/plugin" \
-H "Authorization: Bearer ${OPENHANDS_API_KEY}" \
-H "Content-Type: application/json" \
-d '{
"name": "Code Review Automation",
"plugins": [
{"source": "github:owner/code-review-plugin", "ref": "v2.0.0"}
],
"prompt": "Review all Python files in the repository for code quality issues",
"trigger": {"type": "cron", "schedule": "0 9 * * 1-5", "timezone": "UTC"}
}'
Multiple plugins:
curl -X POST "https://app.all-hands.dev/api/automation/v1/preset/plugin" \
-H "Authorization: Bearer ${OPENHANDS_API_KEY}" \
-H "Content-Type: application/json" \
-d '{
"name": "Security Scan Automation",
"plugins": [
{"source": "github:owner/security-scanner"},
{"source": "github:owner/report-generator", "ref": "main"}
],
"prompt": "Run a security scan on the codebase and generate a report",
"trigger": {"type": "cron", "schedule": "0 2 * * 0", "timezone": "UTC"},
"timeout": 600
}'
Monorepo plugin:
curl -X POST "https://app.all-hands.dev/api/automation/v1/preset/plugin" \
-H "Authorization: Bearer ${OPENHANDS_API_KEY}" \
-H "Content-Type: application/json" \
-d '{
"name": "Style Guide Enforcement",
"plugins": [
{"source": "github:company/monorepo", "repo_path": "plugins/style-guide", "ref": "main"}
],
"prompt": "Check all files against the company style guide",
"trigger": {"type": "cron", "schedule": "0 8 * * 1", "timezone": "America/Los_Angeles"}
}'
curl "https://app.all-hands.dev/api/automation/v1?limit=20" \
-H "Authorization: Bearer ${OPENHANDS_API_KEY}"
# Get details
curl "https://app.all-hands.dev/api/automation/v1/{automation_id}" \
-H "Authorization: Bearer ${OPENHANDS_API_KEY}"
# Update (fields: name, trigger, enabled, timeout)
curl -X PATCH "https://app.all-hands.dev/api/automation/v1/{automation_id}" \
-H "Authorization: Bearer ${OPENHANDS_API_KEY}" \
-H "Content-Type: application/json" \
-d '{"enabled": false}'
# Delete
curl -X DELETE "https://app.all-hands.dev/api/automation/v1/{automation_id}" \
-H "Authorization: Bearer ${OPENHANDS_API_KEY}"
# Manually trigger a run
curl -X POST "https://app.all-hands.dev/api/automation/v1/{automation_id}/dispatch" \
-H "Authorization: Bearer ${OPENHANDS_API_KEY}"
# List runs
curl "https://app.all-hands.dev/api/automation/v1/{automation_id}/runs?limit=20" \
-H "Authorization: Bearer ${OPENHANDS_API_KEY}"
Run status values: PENDING (waiting for dispatch), RUNNING (in progress), COMPLETED (success), FAILED (check error_detail).
After a run completes, the sandbox is kept alive by default — users can view the conversation history in the OpenHands UI and continue interacting. The sandbox persists until it times out or is manually deleted.
| Use Case | Recommended Preset | |----------|-------------------| | Simple tasks with natural language prompt | Prompt Preset | | Need plugin skills, MCP configs, or commands | Plugin Preset | | Custom dependencies or non-Python entrypoint | Custom Automation (see below) |
The prompt preset covers most use cases. Use the plugin preset when you need extended capabilities from plugins (skills, MCP configurations, hooks, commands). The plugin preset fetches plugins at runtime from their sources and loads them into the conversation.
When neither preset is sufficient (e.g., custom Python dependencies, non-Python entrypoint, multi-file project structure, direct SDK lifecycle control), explain the options to the user and let them decide. Do not attempt custom automation without explicit user request. If they choose the custom route, refer to references/custom-automation.md.
references/custom-automation.md — Detailed guide for custom automations: tarball uploads, SDK code structure, environment variables, validation rules, and complete examples. Only use when the user explicitly requests a custom automation.tools
Create an automation that generates an async standup digest from Slack. Searches selected channels for messages since the previous workday, groups updates by project, highlights blockers and decisions, and posts a summary to a target channel.
tools
Create an automation that writes a recurring research brief. Uses Tavily MCP for web research and Notion MCP to publish the final brief with executive summary, implications, and source citations.
tools
Create an automation that triages new Linear issues. Inspects the issue title, description, team, customer, priority, and recent related issues via Linear MCP. Suggests labels, priority, likely owner, duplicates, and posts a clarifying comment.
tools
Create an automation that drafts incident retrospectives. Gathers incident-channel messages from Slack, collects linked tickets and follow-ups from Linear, and publishes a retrospective draft to Notion with a timeline, impact summary, root-cause hypotheses, and action items.