Create
Create a new scheduled job that runs an agent prompt on a cron schedule and posts results to a Slack or Discord channel. Returns the created job ID.
You'll need a platform channel_id from Channels to create a scheduled job. Pass that channel_id (for example C09M8FRJYTF for Slack, or the numeric snowflake for Discord) as connected_channel_id, not the internal cc_… record ID.
See Schedule rules for cron format and timezone requirements.
POST /api/public/v1/scheduled-jobsRequest body
Prop
Type
Example
curl -X POST https://api.nairi.ai/api/public/v1/scheduled-jobs \
-H "Authorization: Bearer $NAIRI_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"schedule": "0 9 * * *",
"timezone": "America/New_York",
"prompt": "Generate daily status report",
"connected_channel_id": "C09M8FRJYTF",
"job_type": "slack",
"is_threaded": true,
"is_enabled": true
}'const res = await fetch("https://api.nairi.ai/api/public/v1/scheduled-jobs", {
method: "POST",
headers: {
Authorization: `Bearer ${process.env.NAIRI_API_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
schedule: "0 9 * * *",
timezone: "America/New_York",
prompt: "Generate daily status report",
connected_channel_id: "C09M8FRJYTF",
job_type: "slack",
is_threaded: true,
is_enabled: true,
}),
});
const data = (await res.json()) as { id: string };require "net/http"
require "json"
require "uri"
uri = URI("https://api.nairi.ai/api/public/v1/scheduled-jobs")
req = Net::HTTP::Post.new(uri)
req["Authorization"] = "Bearer #{ENV['NAIRI_API_KEY']}"
req["Content-Type"] = "application/json"
req.body = {
schedule: "0 9 * * *",
timezone: "America/New_York",
prompt: "Generate daily status report",
connected_channel_id: "C09M8FRJYTF",
job_type: "slack",
is_threaded: true,
is_enabled: true,
}.to_json
res = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |h| h.request(req) }
data = JSON.parse(res.body)import os
import requests
res = requests.post(
"https://api.nairi.ai/api/public/v1/scheduled-jobs",
headers={
"Authorization": f"Bearer {os.environ['NAIRI_API_KEY']}",
"Content-Type": "application/json",
},
json={
"schedule": "0 9 * * *",
"timezone": "America/New_York",
"prompt": "Generate daily status report",
"connected_channel_id": "C09M8FRJYTF",
"job_type": "slack",
"is_threaded": True,
"is_enabled": True,
},
)
data = res.json()package main
import (
"bytes"
"encoding/json"
"fmt"
"io"
"net/http"
"os"
)
func main() {
body, _ := json.Marshal(map[string]any{
"schedule": "0 9 * * *",
"timezone": "America/New_York",
"prompt": "Generate daily status report",
"connected_channel_id": "C09M8FRJYTF",
"job_type": "slack",
"is_threaded": true,
"is_enabled": true,
})
req, _ := http.NewRequest("POST", "https://api.nairi.ai/api/public/v1/scheduled-jobs", bytes.NewReader(body))
req.Header.Set("Authorization", "Bearer "+os.Getenv("NAIRI_API_KEY"))
req.Header.Set("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
raw, _ := io.ReadAll(res.Body)
var data map[string]any
json.Unmarshal(raw, &data)
fmt.Println(data)
}Response: 201 Created
{
"id": "sj_01K7XSRBBM0294N1WBD2M9EVQC",
"schedule": "0 9 * * *",
"timezone": "America/New_York",
"prompt": "Generate daily status report",
"connected_channel_id": "C09M8FRJYTF",
"job_type": "slack",
"is_threaded": true,
"is_enabled": true,
"last_executed_at": "2026-04-12T18:45:12.000Z",
"created_at": "2026-04-12T18:45:12.000Z",
"updated_at": "2026-04-12T18:45:12.000Z"
}On create, last_executed_at is set to creation time (not null), even when is_enabled is false. This prevents the job from firing immediately the moment it is enabled.
List
List every scheduled job in your Nairi organization with its cron schedule, target agent, target channel, and current enabled state. Paginated response.
Get
Fetch a single scheduled job by ID from your Nairi organization. Returns the cron schedule, prompt, target channel, enabled state, and next run time.