Skip to content

Run statistics

GET /api/v1/run_stats reports aggregated statistics over your account's runs. One request answers the common monitoring questions: how many runs matched the filters (total), how they broke down by lifecycle state (tally), how they were distributed over time (buckets, when the bucket directive is given), which runs failed most recently (recent_failures, at most 3, newest first), and what fires next (next_scheduled) — so a dashboard or monitor gets run health in one read instead of paging the full runs list.

The resource type is run_stat and its id is always current — statistics are computed at read time, not stored.

Scoping the statistics

Filters compose with AND:

ParameterNotes
filter[created_at]Restrict the statistics to runs whose created_at falls in a half-open [start,end) interval. Bounds are ISO-8601 timestamps; * leaves a bound open. The leading bracket is [ (inclusive) or ( (exclusive) and the trailing bracket is ] (inclusive) or ) (exclusive). Example: [2026-06-01T00:00:00Z,*) covers everything from June 1 onward. Does not apply to next_scheduled.
filter[environment]One environment key or a comma-separated list to match any (e.g. production,staging). Omit it to cover every environment you can access.
bucketA directive, not a filter: also return run counts over time, grouped into buckets of this size — one of 1m, 5m, 15m, 1h, 6h, or 1d. Omit to skip the time series.

next_scheduled honors only the environment filter: it reports the soonest PENDING run with a fire time at or after the request, no matter when that run was created.

What comes back

FieldNotes
totalRuns matching the filters.
tallyThose runs counted by lifecycle state: { pending, running, succeeded, failed, canceled } — the same states as a run's status.
bucketsRun counts over time at the requested bucket granularity — a list of { bucket, count } ordered by bucket start, where bucket is the start of the bucket (UTC) and count is the runs created within it. Buckets are aligned to the epoch — e.g. 1h buckets start on the hour. null when the request did not include the bucket directive.
recent_failuresThe most recently created FAILED runs matching the filters, newest first — at most 3. Each entry is { job, job_name, failure_reason, created_at }, where failure_reason is the run's failure reason (null when unrecorded).
next_scheduledThe soonest PENDING run with a fire time at or after the request — { job, job_name, scheduled_for, environment } — or null when nothing upcoming is scheduled. The filter[created_at] range does not apply here: a run scheduled long ago for a future fire time is still next.

In recent_failures and next_scheduled, job is the job's slug and job_name is its display name, resolved at read time — null when the job no longer exists.

Sparse buckets

Only buckets containing at least one run are listed — treat missing buckets as zero.

Example

Run health for production since June 5, bucketed by hour:

curl -H "Authorization: Bearer $SMPLKIT_API_KEY" \
     "https://jobs.smplkit.com/api/v1/run_stats?filter[created_at]=[2026-06-05T00:00:00Z,*)&filter[environment]=production&bucket=1h"
json
{
  "data": {
    "id": "current",
    "type": "run_stat",
    "attributes": {
      "total": 42,
      "tally": { "pending": 1, "running": 0, "succeeded": 39, "failed": 2, "canceled": 0 },
      "buckets": [
        { "bucket": "2026-06-05T00:00:00Z", "count": 17 },
        { "bucket": "2026-06-05T01:00:00Z", "count": 25 }
      ],
      "recent_failures": [
        { "job": "nightly_backup", "job_name": "Nightly database backup", "failure_reason": "NON_SUCCESS_STATUS", "created_at": "2026-06-05T01:12:00Z" }
      ],
      "next_scheduled": { "job": "nightly_backup", "job_name": "Nightly database backup", "scheduled_for": "2026-06-06T02:00:00Z", "environment": "production" }
    }
  }
}