Scheduler — Cloud Function reference
Cron for agents — the database wakes the agent. See the Scheduler subsystem for the narrative.
createJob
Caller: authenticated agent onCall
createJob({
name: string;
cron: string; // standard 5-field cron expression
webhookUrl: string;
payload?: unknown; // forwarded verbatim to the webhook body
maxAttempts?: number; // default 5
}) => {ok: true}
Errors
| Code | Reason |
|---|---|
invalid-argument | name/cron/webhookUrl missing or cron invalid |
resource-exhausted | scheduler.createJob quota exhausted |
Side effects
- Writes
agents/{agentId}/jobs/{name}with a freshly-generated 256-bithmacSecret - Computes
nextRunAtfrom the cron expression - Audit:
scheduler.createJobwith{cron}
dispatch
Caller: Cloud Scheduler (internal, every 1 minute) onSchedule — not callable by users
Pages up to 50 due jobs (enabled == true && nextRunAt <= now) and
dispatches each:
- Creates a
runs/{runId}doc withstatus: 'running',attempt: 1 - Signs the body:
HMAC-SHA256(hmacSecret, JSON.stringify({job, payload})) - POSTs to
webhookUrlwith headerx-ujex-signature: <hex> - Updates the run doc:
status,responseCode,finishedAt - Advances
nextRunAtvia the cron schedule
Your webhook
Ujex expects the webhook endpoint to:
- Accept
POST - Verify
x-ujex-signatureagainst the body with thehmacSecretreturned at job creation - Return
2xxfor success, any other status counts as a failed run
The request body shape:
{
"job": "daily-digest",
"payload": { "...": "whatever you passed to createJob" }
}
dlqReplay
Caller: authenticated human (owner of agentId)
onCall
dlqReplay({
agentId: string;
jobName: string;
runId: string; // the specific failed run to re-queue
}) => {ok: true}
Errors
| Code | Reason |
|---|---|
permission-denied | Caller does not own agentId |
Behaviour
- Updates the run doc:
status: 'queued',attempt: +1 - The next
dispatchtick will pick it up
Firestore state
| Path | Written by | Contents |
|---|---|---|
agents/{agentId}/jobs/{name} | createJob | name, cron, webhookUrl, payload, hmacSecret, maxAttempts, enabled, nextRunAt, timestamps |
agents/{agentId}/jobs/{name}/runs/{runId} | dispatch | status, attempt, startedAt, finishedAt, responseCode, error |
audit/{seq} | createJob | scheduler.createJob event |
Quota bucket
| Bucket | Charged by | Credited by |
|---|---|---|
scheduler.createJob | successful job creation | job creation failure after meter |
SLO target
The reference deployment targets dead-letter ratio < 1% of runs and the median dispatch latency under 2 minutes (cron minute + dispatch tick).