Repository navigation
API Jobs
Caligrafy Quill 2.26.0. Generated from the source by
php qa/build-api-reference.php; the guides explain how to use these classes, this reference says exactly what each public method takes and returns. Back to the API reference.
Scheduled jobs, background jobs, web push and email notifications, mail.
| Class | What it is |
|---|---|
Caligrafy\Scheduler |
An app declares its jobs in application/config/schedule.php: each one calls one capability with fixed inputs on a fixed rhythm (every: 1m...1d, or a five-field cron in a timezone). |
Caligrafy\Queue |
A job is a capability and its input, kept in the caligrafy_jobs table (php caligrafer.php platform install, or the deploy step, creates it). |
Caligrafy\Notify |
Notify::user($userId, ['title' => ..., 'body' => ..., 'url' => ..., 'tag' => ..., 'urgency' => ...]) sends to every channel the user turned on and logs the result (caligrafy_notifications: never the body; kept 30 days): ... |
Caligrafy\Mail |
The Mail class handles all emails sent from the framework |
namespace Caligrafy;
class SchedulerSource: framework/core/Scheduler.php:22
Class Scheduler An app declares its jobs in application/config/schedule.php: each one calls one capability with fixed inputs on a fixed rhythm (every: 1m...1d, or a five-field cron in a timezone). The framework validates the file, runs the jobs locally (php caligrafer.php schedule due / work) and prints the listing Caligrafy Cloud runs in production (schedule list --json, version 1).
A run: one at a time per job (a database lock), in a child process stopped at its timeout, with full access like the command line (Context::system: actor type schedule, actor id the job's name), recorded in caligrafy_job_runs (kept 30 days). Exit codes: 0 ok, 1 the capability failed or timed out, 2 the schedule file is invalid, 3 skipped.
FILE = 'application/config/schedule.php'TABLE = 'caligrafy_job_runs'LISTING_VERSION = 1EVERY = ...DEFAULT_TIMEOUT = 55MAX_TIMEOUT = 300KEEP_DAYS = 30FIELDS = array('name', 'capability', 'input', 'every', 'cron', 'timezone', 'timeout', 'enabled')OK = 0FAILED = 1INVALID = 2SKIPPED = 3
->__construct()->jobs()Scheduler::validate()Scheduler::listing()Scheduler::parse()Scheduler::isDue()->run()->execute()->dueAt()->due()->work()Scheduler::history()Scheduler::spawn()
public function __construct($root = '.')No doc comment.
Parameters
-
$root, default'.'
Source: framework/core/Scheduler.php:42
public function jobs($capabilities = true)The jobs of the project's schedule file, validated and completed (an empty list when there is no file)
Parameters
-
$capabilitiesbool, defaulttrue: also check that each capability exists -
@throws \InvalidArgumentException with every problem, one per line
Source: framework/core/Scheduler.php:55
public static function validate(array $declared, ?callable $exists = null)Validates declared jobs and completes them (cron from every, timezone, timeout, enabled)
Parameters
-
$declaredarray: the array the schedule file returns -
$exists?callable, defaultnull: tells whether a capability exists (null: not checked)
Returns array: the jobs, in the file's order
- @throws \InvalidArgumentException with every problem, one per line
Source: framework/core/Scheduler.php:75
public static function listing(array $jobs)The listing Caligrafy Cloud reads at deploy time (schedule list --json): the enabled jobs, every as cron
Parameters
-
$jobsarray
Source: framework/core/Scheduler.php:149
public static function parse($cron)The allowed values of each field of a five-field cron (minute hour day-of-month month day-of-week)
Parameters
$cron
Returns array: five sorted lists of integers (day of week: 0-6, Sunday is 0 or 7)
- @throws \InvalidArgumentException
Source: framework/core/Scheduler.php:168
public static function isDue($cron, \DateTimeInterface $at, $timezone = 'UTC')Whether a cron is due at a time (to the minute), read in a timezone. When both the day of the month and the day of the week are restricted, either one matches (as in cron)
Parameters
$cron-
$at\DateTimeInterface -
$timezone, default'UTC'
Source: framework/core/Scheduler.php:225
public function run($name, ?callable $say = null, $ifDue = false)Runs one job now: takes its lock, runs it in a child process (stopped at its timeout), records the run
Parameters
-
$namestring: the job's name -
$say?callable, defaultnull: prints a line -
$ifDuebool, defaultfalse: only when the job is due this minute in its timezone (--if-due), else nothing is run or recorded
Returns int: an exit code (OK, FAILED, SKIPPED)
Source: framework/core/Scheduler.php:254
public function execute($name)What a run's child process does: calls the job's capability as the scheduler and prints the result as JSON
Parameters
$name
Returns int: OK or FAILED
Source: framework/core/Scheduler.php:286
public function dueAt(\DateTimeInterface $at)The jobs due in a minute (enabled ones only)
Parameters
-
$at\DateTimeInterface
Source: framework/core/Scheduler.php:305
public function due(?callable $say = null, ?\DateTimeInterface $at = null)Runs every job due in the current minute, side by side, and waits for them
Parameters
-
$say?callable, defaultnull -
$at?\DateTimeInterface, defaultnull
Returns int: OK when every run is ok or skipped, FAILED otherwise
Source: framework/core/Scheduler.php:316
public function work(?callable $say = null)Runs schedule due at the start of every minute until stopped (local development)
Parameters
-
$say?callable, defaultnull
Source: framework/core/Scheduler.php:341
public static function history($name = null, $limit = 50)The latest runs, newest first
Parameters
-
$name, defaultnull -
$limit, default50
Source: framework/core/Scheduler.php:358
public static function spawn(array $args, $root, $timeout)Runs php caligrafer.php <args> in $root, stopped after $timeout seconds (the scheduler's jobs, the queue's jobs)
Parameters
-
$argsarray $root$timeout
Returns array: [exit code, or null when it was stopped, or false when it could not start; its output]
Source: framework/core/Scheduler.php:400
namespace Caligrafy;
class QueueSource: framework/core/Queue.php:26
Class Queue (2.18.0)
Queue::push('send_welcome_email', ['user_id' => $id]); // as soon as a worker is free
Queue::push('build_report', ['month' => '2026-11'], ['delay' => 600, 'attempts' => 5, 'timeout' => 120]);
A job is a capability and its input, kept in the caligrafy_jobs table (php caligrafer.php platform install, or the deploy step, creates it). A worker runs each one in its own process, stopped at its timeout, with full access, as a scheduled job (Context::system('queue', '<capability> #<id>')): check who may ask for the work before pushing it.
Workers: php caligrafer.php queue work (a loop, on your computer or your own server), or the scheduler: a job of application/config/schedule.php on the framework's capability queue_work, every minute, which Caligrafy Cloud runs too. A failed run is tried again after 30 s, 1 min, 2 min... until its attempts are used; an input the capability refuses (invalid, not found) fails at once. Jobs are kept 7 days after they finish.
TABLE = 'caligrafy_jobs'DEFAULT_ATTEMPTS = 3DEFAULT_TIMEOUT = 60MAX_TIMEOUT = 900RETRY_SECONDS = 30KEEP_DAYS = 7NAME = '/^[a-z0-9_-]{1,40}$/'
public static function push($capability, array $input = array(), array $options = array())Adds a job
Parameters
$capability-
$inputarray, defaultarray() -
$optionsarray, defaultarray(): delay (seconds), attempts (1-20), timeout (seconds), queue (a name, default)
Returns int: the job's id
Source: framework/core/Queue.php:41
public static function work(array $options = array())Runs jobs: until none is left (once), for $seconds, or forever
Parameters
-
$optionsarray, defaultarray(): queue (default), seconds (stop starting jobs after), once (stop when empty), sleep (seconds between looks when empty), root (the project), say (callable)
Returns array: counts: done, retried, failed
Source: framework/core/Queue.php:69
public static function execute($id)The child process of a job (php caligrafer.php queue exec <id>): calls its capability, prints its answer as JSON
Parameters
$id
Returns int: 0 done, 1 failed (try again), 2 refused (do not try again)
Source: framework/core/Queue.php:111
public static function jobs($status = null, $limit = 50)Jobs, newest first
Parameters
-
$statusstring|null, defaultnull: pending, running, done or failed -
$limit, default50
Source: framework/core/Queue.php:136
public static function counts()How many jobs are in each state
Source: framework/core/Queue.php:150
public static function retry($id = null)Puts failed jobs back in the queue with new attempts: one id, or all (null)
Parameters
-
$id, defaultnull
Returns int: how many
Source: framework/core/Queue.php:163
Notify::user($userId, ['title' => ..., 'body' => ..., 'url' => ..., 'tag' => ..., 'urgency' => ...]) sends to every channel the user turned on and logs the result (caligrafy_notifications: never the body; kept 30 days): ...
Its 20 public methods have a page of their own: Caligrafy\Notify.
namespace Caligrafy;
class Mail extends \stdClassSource: framework/core/Mail.php:24
The Mail class handles all emails sent from the framework
public function __construct()No doc comment.
Source: framework/core/Mail.php:32
public function sendMail($recipients, $emailContent, $from, array $headers = array())Parameters
$recipients$emailContent$from-
$headersarray, defaultarray(): extra headers, name => value (Notify: List-Unsubscribe, List-Unsubscribe-Post)
Source: framework/core/Mail.php:73
Caligrafy: Describe it. Approve it. Ship it. Your idea turned into a complete app: every feature built once, for web pages, Vue apps, a REST API and AI agents, and online.
Why Caligrafy: the benefits, the measurements, and what it is not yet
-
Quickstart with Claude: describe it, approve it, ship it
or the Quickstart: the same three steps by hand, in 5 minutes
- How Caligrafy works: the ideas in 5 minutes
- Your first capability: build a feature, page included
-
Capabilities in depth
-
#[Capability]: every option - Scheduled jobs: capabilities on a timer
- Notifications: web push and email
- Background jobs: capabilities run later
- Migrations: database changes, in order
- The cache
-
Testing your app
- Dependency injection
- Validation rules
-
Web pages
- Views and page components
- Design styles: another look, one setting
- Declarative routes: every request, in one line
-
Route::page·Route::form·Route::auth·Route::webhook·Route::download·Route::redirect·Route::action·Route::snap· capability routes - How to export a list as CSV
- Controllers: moving one to a declared route · how to, step by step
- Forms and helpers
-
Vue apps
-
Mobile and tablet
-
REST API
-
AI agents
-
Snap Cards and the assistant
- Payments: Stripe and crypto
- Face detection and face login
- OpenAI: chat and images · Assistants
- Open models: Llama, Mistral...
- Chatbots with Watson
- Machine learning in the browser
- Metadata and social cards · search and analytics
-
Putting it online: the production image, the database at every start
-
API reference: every class and method
-
Routing ·
Route·AuthRoutes· pages ·Controller· capabilities -
Data ·
Model·Query· sign-in · jobs ·Notify· payments · AI -
Interfaces · Snap ·
Snap\Cards·Snap\Conversation· testing · tooling · helper functions
-
Routing ·
-
Caligrafer: every command
- Project · build · data · agents · jobs and tests · maintenance · deploy
- Installation, configuration and Caligrafer
- Routing · Request · Controllers · Views
- Vue: flow of information · routes · validations
- Security and upgrading
- Release notes: 2.26 · 2.25 · 2.24 · 2.23 · 2.22 · 2.21 · 2.20 · 2.19 · 2.18 · 2.17 · 2.16 · 2.15 · 2.14 · 2.13 · 2.12 · 2.11 · 2.10 · 2.9 · 2.8 · 2.7 · 2.6 · 2.5 · 2.4 · 2.3 · 2.1 · October 2026 · changelog
- Testing Caligrafy (contributors)