# 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.

```http
GET /api/public/v1/scheduled-jobs/{id}/runs
```

Requires an API key with the `automations:read` scope.

## Query parameters [#query-parameters]

| Parameter | Type    | Default | Description                 |
| --------- | ------- | ------- | --------------------------- |
| `limit`   | integer | `20`    | Runs per page, at most 100. |
| `offset`  | integer | `0`     | How many runs to skip.      |

## Example [#example]

<Tabs items="[&#x22;bash&#x22;, &#x22;TypeScript&#x22;, &#x22;Ruby&#x22;, &#x22;Python&#x22;, &#x22;Go&#x22;]">
  <Tab value="bash">
    ```bash
    curl -s "https://api.nairi.ai/api/public/v1/scheduled-jobs/SCHEDULED_JOB_ID/runs?limit=5" \
      -H "Authorization: Bearer $NAIRI_API_KEY"
    ```
  </Tab>

  <Tab value="TypeScript">
    ```ts
    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;
    }>;
    ```
  </Tab>

  <Tab value="Ruby">
    ```ruby
    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)
    ```
  </Tab>

  <Tab value="Python">
    ```python
    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()
    ```
  </Tab>

  <Tab value="Go">
    ```go
    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)
    }
    ```
  </Tab>
</Tabs>

## Response: `200 OK` [#response-200-ok]

```json
[
  {
    "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 [#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](/api/conversations/message-reference) 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 [#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.                  |
