jscheduler
field manual / v0.1

Quickstart / first successful POST

From zero to a delivered webhook.

jscheduler is an HTTP scheduler, not a job runtime. You give it a schedule and JSON payload; when the minute arrives, it POSTs an occurrence to an endpoint you control.

YOU NEEDAn organization + API key
YOUR SERVER NEEDSA public HTTPS endpoint
ALLOWUp to two minutes for this run
01.1

Install and authenticate

The CLI ships as a native macOS or Linux binary. Login verifies the key before saving it to ~/.jscheduler/config.json.

terminalcopy / run
curl -fsSL https://cli.jscheduler.com/install.sh | bash
jscheduler auth login --api-key jsk_your_key
01.2

Set the default endpoint

Every organization needs one untagged endpoint. It is the fallback destination for every event that does not match a tag-specific route.

terminalcopy / run
jscheduler endpoints create \
  --url https://example.com/webhooks/jscheduler
01.3

Schedule the first event

All schedule timestamps must land exactly on a minute. Choose a future UTC minute, then create the event:

terminalcopy / run
jscheduler events create \
  --name trial.expiring \
  --kind ONE_TIME \
  --fire-at 2030-07-13T09:00:00Z \
  --tags lifecycle \
  --payload '{"accountId":"acct_42"}'

Prefer raw HTTP? The API uses the same tenant key:

http / jsoncopy / run
curl https://api.jscheduler.com/scheduled-events \
  -H "Authorization: Bearer $JSCHEDULER_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "eventName": "trial.expiring",
    "externalId": "trial_acct_42",
    "tags": ["lifecycle"],
    "payload": {"accountId": "acct_42"},
    "schedule": {
      "kind": "ONE_TIME",
      "fireAt": "2030-07-13T09:00:00Z"
    }
  }'

02 / Schedules

Three ways to name a minute.

ONE_TIME

Exactly once

Requires fireAt. A successful occurrence completes the runtime.

INTERVAL

Every N minutes

Requires intervalMinutes and startAt. The next time advances without drift.

CRON

UTC calendar

Five structured cron fields. Month and weekday names are accepted; seconds are not.

weekday croncopy / run
jscheduler events create \
  --name weekday.report \
  --kind CRON \
  --cron "0 9 * * MON-FRI" \
  --payload '{"report":"daily"}'

03 / Delivery contract

What arrives at your endpoint.

jscheduler sends an HTTP POST with Content-Type: application/json and an Idempotency-Key header equal to the occurrence id.

POST bodycopy / run
{
  "occurrenceId": "8c9…:2026-07-13T09:00:00Z",
  "scheduledEventId": "8c9…",
  "scheduledFor": "2026-07-13T09:00:00Z",
  "eventName": "trial.expiring",
  "externalId": "trial_acct_42",
  "tags": ["lifecycle"],
  "payload": {"accountId": "acct_42"},
  "attempt": 1
}
A / DEFAULT

RECEIVER_IDEMPOTENT

Retries retryable failures automatically. Your receiver should store or otherwise deduplicate the idempotency key.

B / CONSERVATIVE

NO_DUPLICATE_SENDS

An ambiguous outcome becomes UNCERTAIN instead of risking another automatic send. You decide whether to redrive.

04 / Endpoint routing

Default first. Tags when needed.

Create one default endpoint, then optional routes for event tags. A tag-specific match wins; the default catches everything else.

terminalcopy / run
jscheduler endpoints create --url https://example.com/hooks
jscheduler endpoints create --tag billing --url https://billing.example.com/hooks
jscheduler endpoints list

05 / Recovery

Inspect. Decide. Redrive.

Delivery history includes status, attempts, completion time, and the last receiver or network error.

terminalcopy / run
jscheduler events deliveries <event-id>
jscheduler events redrive <event-id> <delivery-id>

Only FAILED or UNCERTAIN deliveries can be redriven. The operation keeps the same occurrence id so receiver-side deduplication remains valid.

06 / Tenant API surface

The compact reference.

GET/endpoints

List endpoint routes

POST/endpoints

Create an endpoint route

DELETE/endpoints/{endpointId}

Delete a route

GET/scheduled-events

List and search events

POST/scheduled-events

Create an event

GET/scheduled-events/{id}

Read event state

POST/scheduled-events/{id}/disable

Pause future occurrences

POST/scheduled-events/{id}/enable

Resume an event

GET/scheduled-events/{id}/executions

Read execution history

GET/scheduled-events/{id}/deliveries

Read delivery history

POST/scheduled-events/{id}/deliveries/{deliveryId}/redrive

Retry terminal delivery

Ready for the clock?

Request an organization and API key.

Request access