Scheduled jobs
Scheduled jobs in Nautilus are the Clockwork API (/v1/clockwork/*, for API keys with the clockwork scope): HTTP calls on a cron schedule or at a set time, run and recorded for you, with no cron daemon or queue worker of your own. The same scheduler runs the automatic deletion of inactive accounts. This section calls it Clockwork wherever it names the API.
How it works
Clockwork lets you schedule HTTP callbacks on two execution models:
- Cron Jobs — recurring tasks defined by a 5-field cron expression (e.g.
0 * * * *for every hour). Note that a schedule may restrict day-of-month or day-of-week, but not both — see the API reference. A schedule is read in UTC unless you give the job an IANAtimezonesuch asEurope/Paris; the job then keeps its local wall-clock time through daylight-saving changes, with defined rules for the hour that is skipped in spring and the hour that repeats in autumn. - Delayed Jobs — one-shot tasks fired at a specific future timestamp.
In both cases, Clockwork's worker picks up the job at the right time and makes an HTTP request to any URL you configure — your own API, a webhook, a microservice endpoint, or a third-party integration.
Under the hood, Clockwork is a purpose-built Rust worker (clockwork_worker) with atomic job claiming to prevent double-execution across concurrent instances, automatic retries for failures worth repeating, and a full execution history covering every attempt.
What you get
| Capability | Description |
|---|---|
| Reliable Scheduling | Atomic DB claim prevents double-execution across concurrent worker instances. |
| Automatic Retries | Network failures, 5xx and 429 are retried up to 3 times with a growing delay. A 4xx is not — see Retries. |
| Full Execution History | Every attempt is recorded with status, duration, HTTP response code, and error details. |
| Flexible HTTP Dispatch | Any HTTP method (GET / POST / PUT / PATCH / DELETE), custom headers, and optional body. |
| Dashboard UI | Manage and monitor all jobs from the dashboard without writing infrastructure code. |
| Included in your plan | Scheduled runs and Clockwork API calls are not counted or billed. Each plan limits how many jobs are active at once and how long run history is kept — see Plan Limits. |
| Multi-tenant | Each tenant's jobs and execution history are strictly isolated. |
| Zero Ops | No queues to manage, no cron daemons to maintain — just an API call or a few clicks. |
Quick Start
- Log in and open Scheduled jobs in the dashboard.
- Go to the Cron Jobs tab to create a recurring job, or the Delayed Jobs tab to schedule a one-shot task.
- Fill in the target URL, HTTP method, schedule (cron expression or datetime), and optional headers/body.
- Click Create — Clockwork handles the rest.
Or use the API directly from your backend with an API key with the clockwork scope (create one on Dashboard → API Keys, with Scheduled jobs ticked):
# Create a cron job that pings your health endpoint every 5 minutes
curl -X POST https://api.vernesoft.com/v1/clockwork/jobs \
-H "Authorization: Bearer vrn_9f8a7..." \
-H "Content-Type: application/json" \
-d '{
"name": "Health ping",
"schedule": "*/5 * * * *",
"url": "https://yourapp.com/health",
"method": "GET"
}'
# Schedule a one-shot job to run at a specific time
curl -X POST https://api.vernesoft.com/v1/clockwork/delayed \
-H "Authorization: Bearer vrn_9f8a7..." \
-H "Content-Type: application/json" \
-d '{
"name": "Send welcome email",
"run_at": "2026-04-10T09:00:00Z",
"url": "https://yourapp.com/internal/send-welcome",
"method": "POST",
"body": "{\"user_id\": \"usr_001\"}"
}'
Authentication
Clockwork can be called two ways, both strictly scoped to a single tenant — Clockwork will never expose or modify another tenant's jobs:
- API key (recommended for backends) — send an API key with the
clockworkscope as a Bearer token against the/v1/clockwork/*routes. The tenant is derived from the key. Create and rotate keys on Dashboard → API Keys. - Session cookie (Console / browser) — forward the
ory_kratos_sessioncookie against the/dashboard/clockwork/*routes. The session is set automatically when you log in to the dashboard.
Both modes operate on the same jobs and are documented side by side in the API Reference.