Runs
List the conversations a scheduled job has started, newest first, with the status of each and whether the tick or a person fired it.
Lists the jobs a schedule created, newest first.
GET /api/public/v1/scheduled-jobs/{id}/runsRequires an API key with the automations:read scope.
Query parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
limit | integer | 20 | Runs per page, at most 100. |
offset | integer | 0 | How many runs to skip. |
Example
curl -s "https://api.nairi.ai/api/public/v1/scheduled-jobs/SCHEDULED_JOB_ID/runs?limit=5" \
-H "Authorization: Bearer $NAIRI_API_KEY"const url = new URL(
`https://api.nairi.ai/api/public/v1/scheduled-jobs/${scheduledJobId}/runs`,
);
url.searchParams.set("limit", "5");
const res = await fetch(url, {
headers: { Authorization: `Bearer ${process.env.NAIRI_API_KEY}` },
});
const runs = (await res.json()) as Array<{
id: string;
job_type: string;
status: "queued" | "pending" | "completed" | "failed";
agent_id?: string;
trigger: "scheduled" | "manual";
triggered_by?: { type: "user" | "api_key"; id: string };
platform_link?: string;
created_at: string;
updated_at: string;
}>;require "net/http"
require "json"
require "uri"
uri = URI("https://api.nairi.ai/api/public/v1/scheduled-jobs/#{scheduled_job_id}/runs")
uri.query = URI.encode_www_form(limit: 5)
req = Net::HTTP::Get.new(uri)
req["Authorization"] = "Bearer #{ENV['NAIRI_API_KEY']}"
res = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |h| h.request(req) }
runs = JSON.parse(res.body)import os
import requests
res = requests.get(
f"https://api.nairi.ai/api/public/v1/scheduled-jobs/{scheduled_job_id}/runs",
headers={"Authorization": f"Bearer {os.environ['NAIRI_API_KEY']}"},
params={"limit": 5},
)
runs = res.json()package main
import (
"encoding/json"
"fmt"
"io"
"net/http"
"os"
)
func main() {
scheduledJobID := os.Getenv("SCHEDULED_JOB_ID")
req, _ := http.NewRequest(
"GET",
"https://api.nairi.ai/api/public/v1/scheduled-jobs/"+scheduledJobID+"/runs?limit=5",
nil,
)
req.Header.Set("Authorization", "Bearer "+os.Getenv("NAIRI_API_KEY"))
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
raw, _ := io.ReadAll(res.Body)
var runs []map[string]any
json.Unmarshal(raw, &runs)
fmt.Println(runs)
}Response: 200 OK
[
{
"id": "job_01KRK1V46BXS73CSNK2VR35NPJ",
"job_type": "slack",
"status": "completed",
"agent_id": "oncall",
"trigger": "manual",
"triggered_by": { "type": "api_key", "id": "pak_01KGFV0WN7G22N8HWYDWFHAYBG" },
"platform_link": "https://nairi.slack.com/archives/C0AC1J9LF1V/p1776254400000100",
"created_at": "2026-04-12T13:00:00.000Z",
"updated_at": "2026-04-12T13:02:11.000Z"
},
{
"id": "job_01KRJZ8C3QT5E6YB2W7M9K4N1P",
"job_type": "slack",
"status": "completed",
"trigger": "scheduled",
"created_at": "2026-04-11T13:00:00.000Z",
"updated_at": "2026-04-11T13:01:48.000Z"
}
]An empty history is [].
Response fields
| Field | Type | Description |
|---|---|---|
id | string | The conversation this tick started. Slack and Discord runs are read in the channel; app runs are read in the dashboard's Tasks page. The conversations API only serves conversations started through it, so it answers an empty list for these. |
job_type | string | slack, discord or app. |
status | string | queued (waiting for an agent), pending (the agent is working), completed (answered), or failed (the agent hit an error or dropped the run). The same words a message uses. |
agent_id | string | The agent that ran it. Absent when no agent has picked it up yet. |
trigger | string | scheduled when the tick fired it, manual when a person or an API key did. |
triggered_by | object | Who fired a manual run: type is user for the dashboard button or api_key for a call like this one, and id is that user or key id. Absent for scheduled runs. |
platform_link | string | A link to the post in Slack or Discord, when there is one. |
created_at, updated_at | string | UTC, YYYY-MM-DDTHH:MM:SS.sssZ, like every other timestamp on the API. |
Errors
| Status | When |
|---|---|
404 | No scheduled job with that id in your organization. |
400 | limit is not a positive integer, is over 100, or offset is negative. |
403 | The API key does not have the automations:read scope. |
Run now
Fire a scheduled job once, right now, without waiting for its next tick. The run posts to the job's channel like a scheduled one and shows up in its runs history as manual.
Schedule rules
Cron expression format, timezone handling, and validation rules Nairi enforces when you create or update a scheduled job through the REST API.