Scheduler
Scheduled agent tasks, terminal commands, webhooks and chains that run on any of your PCs, phones, watch or cloud VMs — cron or plain words, approvals, retries, failover and live run status.
The codai Scheduler runs work on a timetable across every device you own. The cloud owns each schedule and decides when a run is due; your hosts (the desktop app, codaid on servers and VMs, the phone) claim runs, execute them and report back. One list, one history and the same approvals on the hub, desktop, phone and watch.
What can run
- agent — a codai agent task (
prompt, optionalskill,permissionsread / edit / pr). - shell — a terminal command on a host (
command,cwd,env_names,shell). Secret values never leave the host: the schedule only names the variables. - http — an HTTPS webhook (
method,url,headers,body,expect_status). - chain — run other schedules in order (
steps,stop_on_failure). - phone_action — notify, start an agent, open an app, toggle Wi-Fi or Do Not Disturb on one phone.
When
trigger is a cron expression with a time zone (5 or 6 fields, vixie-cron day semantics), a one-off at, an interval, a trigger event, or after another schedule (on success, failure or always). POST /v1/schedules/preview turns plain words in English or Romanian ("every weekday at 9", "în fiecare zi la 3") into cron and returns the next five runs plus a daylight-saving warning when a run falls in a clock-change window. Missed runs (host asleep, outage) follow misfire: skip, once (default) or all_within the misfire_window_min.
Where
target picks a single host, any host with all the given tags, any online host, the codai cloud, or a cloud_vm of a project. A cloud_vm run (shell or http) goes to the daemon of one of your codai cloud environments in that project; when none is online, the scheduler starts the most recently used stopped environment (one hour of wallet balance required) and the environment's idle timeout stops it again after the run. failover lists tag sets to try when the target is offline. A host claims a run with a 60-second lease (POST /v1/scheduler/claim, FOR UPDATE SKIP LOCKED, so two hosts never take the same run), keeps it alive with heartbeats and reports a result. An expired lease becomes a new attempt that another host can pick up. With native: true and a single-host target the desktop app also mirrors the schedule into the operating system's scheduler (Task Scheduler, launchd or systemd timers) so it fires even when codai is not running.
Safety
- Shell commands need the host's approval. A shell schedule stores the sha256 of
shell, cwd, command, env names. Each host shows you the exact command once and approves that hash (POST /v1/schedules/{id}/approve-command); any edit changes the hash and clears every approval. - Approvals per run.
policy.approval=alwaysoroutside_hours(withquiet_hours) puts runs inawaiting_approval; you get a notification on every device, including the watch, and approve or skip from any of them. - Limits.
policy.max_runs_per_hour, budgets per run and per day (micro-USD),overlap(skip,queue,kill),timeout_sandretrieswithretry_backoff_s. - Alerts. Failures (
alert_on_fail) and runs nobody started withinlate_after_ssend a notification with a deep link to the run.
Pause, skip days and noise control
- Vacation mode.
POST /v1/schedules/pause(optionallyuntil) stops creating runs for all your schedules;POST /v1/schedules/resumeends it, andbackfill: truegives each schedule that missed slots exactly one catch-up run. - Skip days.
policy.skip_daysskips Romanian public holidays (holidays: 'RO', including Orthodox Easter and Pentecost), chosen weekdays or exact dates, in the trigger's time zone. Skipped slots are never created. - Budgets and auto-pause. When today's runs reach
policy.budget_micro_usd_per_daynew runs are skipped with one alert per day. Afterpolicy.pause_after_failuresconsecutive failures (default 3) the schedule disables itself and tells you. - Notify.
notify=on_failure(default),on_change(only when the normalised output differs from the last success: timestamps and ids are ignored),alwaysornever. - Templates.
GET /v1/schedules/templateslists ready-made schedules such as the weekly transcripts digest (summary, decisions, action items, emailed to you every Friday at 17:00).
Heartbeat monitors
For jobs codai does not run (a crontab on a VM, a CI job, a Cloud Scheduler job), create a monitor with POST /v1/heartbeats { name, period_s, grace_s }. The response contains ping_url once. The job calls it:
GET|POST /ping/<token>on success,/ping/<token>/startwhen it starts,/ping/<token>/failon failure, or/ping/<token>/<exit code>.
No success within period_s + grace_s (or a start without a success within the grace) marks the monitor down and alerts every device once; the next success marks it up and tells you it recovered.
# crontab: back up, then report the exit code
0 3 * * * /srv/backup.sh; curl -fsS -m 10 https://ai.codai.ro/ping/<token>/$?bearerAuthAuthorizationBearer <codai_…>A codai API key (codai_ prefix). Ephemeral tokens from POST /v1/tokens are accepted only by the media surfaces matching their scope (/v1/realtime, /v1/audio/*, /v1/embeddings).
x-request-id?stringClient correlation id; echoed back as x-codai-trace-id and persisted on the usage row.
length <= 128application/json- body
until?stringdate-timeresume_policy?string"skip""backfill"OK.
application/json- response
[key: string]?anycurl -X POST 'https://ai.codai.ro/v1/schedules/pause' \ -H 'Content-Type: application/json' \ -d '{}'{}bearerAuthAuthorizationBearer <codai_…>A codai API key (codai_ prefix). Ephemeral tokens from POST /v1/tokens are accepted only by the media surfaces matching their scope (/v1/realtime, /v1/audio/*, /v1/embeddings).
x-request-id?stringClient correlation id; echoed back as x-codai-trace-id and persisted on the usage row.
length <= 128application/json- body
backfill?booleanOK.
application/json- response
[key: string]?anycurl -X POST 'https://ai.codai.ro/v1/schedules/resume' \ -H 'Content-Type: application/json' \ -d '{}'{}bearerAuthAuthorizationBearer <codai_…>A codai API key (codai_ prefix). Ephemeral tokens from POST /v1/tokens are accepted only by the media surfaces matching their scope (/v1/realtime, /v1/audio/*, /v1/embeddings).
x-request-id?stringClient correlation id; echoed back as x-codai-trace-id and persisted on the usage row.
length <= 128OK.
application/json- response
[key: string]?anycurl -X GET 'https://ai.codai.ro/v1/schedules/templates'{}bearerAuthAuthorizationBearer <codai_…>A codai API key (codai_ prefix). Ephemeral tokens from POST /v1/tokens are accepted only by the media surfaces matching their scope (/v1/realtime, /v1/audio/*, /v1/embeddings).
x-request-id?stringClient correlation id; echoed back as x-codai-trace-id and persisted on the usage row.
length <= 128application/json- body
template*stringparams?OK.
application/json- response
[key: string]?anycurl -X POST 'https://ai.codai.ro/v1/schedules/templates' \ -H 'Content-Type: application/json' \ -d '{ "template": "string"}'{}bearerAuthAuthorizationBearer <codai_…>A codai API key (codai_ prefix). Ephemeral tokens from POST /v1/tokens are accepted only by the media surfaces matching their scope (/v1/realtime, /v1/audio/*, /v1/embeddings).
x-request-id?stringClient correlation id; echoed back as x-codai-trace-id and persisted on the usage row.
length <= 128OK.
application/json- response
heartbeats*array<>curl -X GET 'https://ai.codai.ro/v1/heartbeats'{ "heartbeats": [ { "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", "name": "string", "period_s": 0, "grace_s": 0, "tz": "string", "status": "new", "last_ping_at": "2019-08-24T14:15:22Z", "last_start_at": "2019-08-24T14:15:22Z", "last_exit_code": 0, "ping_url": "string", "created_at": "2019-08-24T14:15:22Z", "updated_at": "2019-08-24T14:15:22Z" } ]}bearerAuthAuthorizationBearer <codai_…>A codai API key (codai_ prefix). Ephemeral tokens from POST /v1/tokens are accepted only by the media surfaces matching their scope (/v1/realtime, /v1/audio/*, /v1/embeddings).
x-request-id?stringClient correlation id; echoed back as x-codai-trace-id and persisted on the usage row.
length <= 128application/json- body
name*stringlength <= 120period_s*integer60 <= value <= 2592000grace_s?integer60 <= value <= 604800tz?stringCreated.
application/json- response
A heartbeat monitor.
id*stringuuidname*stringperiod_s*integergrace_s*integertz?stringstatus*string"new""up""late""down""paused"last_ping_at?stringdate-timelast_start_at?stringdate-timelast_exit_code?integerping_url?stringOnly in the create response.
created_at?stringdate-timeupdated_at?stringdate-timecurl -X POST 'https://ai.codai.ro/v1/heartbeats' \ -H 'Content-Type: application/json' \ -d '{ "name": "string", "period_s": 60}'{ "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", "name": "string", "period_s": 0, "grace_s": 0, "tz": "string", "status": "new", "last_ping_at": "2019-08-24T14:15:22Z", "last_start_at": "2019-08-24T14:15:22Z", "last_exit_code": 0, "ping_url": "string", "created_at": "2019-08-24T14:15:22Z", "updated_at": "2019-08-24T14:15:22Z"}bearerAuthAuthorizationBearer <codai_…>A codai API key (codai_ prefix). Ephemeral tokens from POST /v1/tokens are accepted only by the media surfaces matching their scope (/v1/realtime, /v1/audio/*, /v1/embeddings).
id*stringMonitor id.
uuidx-request-id?stringClient correlation id; echoed back as x-codai-trace-id and persisted on the usage row.
length <= 128application/json- body
name?stringlength <= 120period_s?integer60 <= value <= 2592000grace_s?integer60 <= value <= 604800paused?booleanOK.
application/json- response
A heartbeat monitor.
id*stringuuidname*stringperiod_s*integergrace_s*integertz?stringstatus*string"new""up""late""down""paused"last_ping_at?stringdate-timelast_start_at?stringdate-timelast_exit_code?integerping_url?stringOnly in the create response.
created_at?stringdate-timeupdated_at?stringdate-timecurl -X PATCH 'https://ai.codai.ro/v1/heartbeats/497f6eca-6276-4993-bfeb-53cbbbba6f08' \ -H 'Content-Type: application/json' \ -d '{}'{ "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", "name": "string", "period_s": 0, "grace_s": 0, "tz": "string", "status": "new", "last_ping_at": "2019-08-24T14:15:22Z", "last_start_at": "2019-08-24T14:15:22Z", "last_exit_code": 0, "ping_url": "string", "created_at": "2019-08-24T14:15:22Z", "updated_at": "2019-08-24T14:15:22Z"}bearerAuthAuthorizationBearer <codai_…>A codai API key (codai_ prefix). Ephemeral tokens from POST /v1/tokens are accepted only by the media surfaces matching their scope (/v1/realtime, /v1/audio/*, /v1/embeddings).
id*stringMonitor id.
uuidx-request-id?stringClient correlation id; echoed back as x-codai-trace-id and persisted on the usage row.
length <= 128Deleted.
curl -X DELETE 'https://ai.codai.ro/v1/heartbeats/497f6eca-6276-4993-bfeb-53cbbbba6f08'Live status
GET /v1/schedules/stream sends a schedule event whenever a schedule changes or a run moves state on any device, so every screen updates within a second.
import { Codai } from 'codai-sdk';
const codai = new Codai({ apiKey: process.env.CODAI_API_KEY! });
const preview = await codai.schedules.preview({ text: 'every weekday at 9', tz: 'Europe/Bucharest' });
const backup = await codai.schedules.create({
name: 'Nightly backup',
kind: 'shell',
spec: { command: 'restic backup ~/work' },
trigger: { type: 'cron', expr: '0 3 * * *', tz: 'Europe/Bucharest' },
target: { type: 'tags', tags: ['pc'] },
retries: 2,
});
for await (const e of codai.schedules.stream()) console.log(e.op, e.state);from codai import Codai
codai = Codai(api_key="codai_...", device="7f0e3c1a-...")
job = codai.schedules.executor.claim() # host side; None when there is nothing to run
if job:
codai.schedules.executor.result(job["run"]["id"], {"attempt": job["run"]["attempt"], "ok": True, "exit_code": 0})bearerAuthAuthorizationBearer <codai_…>A codai API key (codai_ prefix). Ephemeral tokens from POST /v1/tokens are accepted only by the media surfaces matching their scope (/v1/realtime, /v1/audio/*, /v1/embeddings).
x-request-id?stringClient correlation id; echoed back as x-codai-trace-id and persisted on the usage row.
length <= 128OK.
application/json- response
schedules*array<>curl -X GET 'https://ai.codai.ro/v1/schedules'{ "schedules": [ { "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", "name": "string", "description": "string", "enabled": true, "kind": "agent", "spec": {}, "trigger": {}, "target": {}, "failover": [ [ "string" ] ], "native": true, "policy": {}, "misfire": "skip", "misfire_window_min": 0, "overlap": "skip", "timeout_s": 0, "retries": 0, "retry_backoff_s": 0, "late_after_s": 0, "alert_on_fail": true, "template": "string", "command_hash": "string", "next_run_at": "2019-08-24T14:15:22Z", "last_run_at": "2019-08-24T14:15:22Z", "upcoming": [ "2019-08-24T14:15:22Z" ], "approvals": [ { "device_id": "3bafab7b-4400-4bcf-8e6e-09f954699940", "command_hash": "string", "approved_at": "2019-08-24T14:15:22Z" } ], "created_at": "2019-08-24T14:15:22Z", "updated_at": "2019-08-24T14:15:22Z" } ]}bearerAuthAuthorizationBearer <codai_…>A codai API key (codai_ prefix). Ephemeral tokens from POST /v1/tokens are accepted only by the media surfaces matching their scope (/v1/realtime, /v1/audio/*, /v1/embeddings).
x-request-id?stringClient correlation id; echoed back as x-codai-trace-id and persisted on the usage row.
length <= 128application/json- body
Schedule fields. kind selects the shape of spec: agent {prompt, skill?, permissions?}, shell {command, cwd?, env_names?, shell?}, http {method?, url, headers?, body?, expect_status?}, chain {steps, stop_on_failure?}, phone_action {action, params?}.
name*stringlength <= 120description?stringenabled?booleankind*string"agent""shell""http""chain""phone_action"spec*trigger*cron {type, expr, tz}, at {type, at}, interval {type, every_s}, event {type, trigger_id} or after {type, schedule_id, on}.
target?host {type, device_id}, tags {type, tags}, any, cloud or cloud_vm {type, project_id}.
failover?array<array<string>>native?booleanpolicy?Approval (never, always, outside quiet hours), quiet hours, budgets per run and per day (micro-USD) and the hourly run limit.
misfire?string"skip""once""all_within"misfire_window_min?integeroverlap?string"skip""queue""kill"timeout_s?integerretries?integerretry_backoff_s?integerlate_after_s?integeralert_on_fail?booleantemplate?stringCreated.
application/json- response
A scheduled task.
id*stringuuidname*stringlength <= 120description?stringenabled*booleankind*string"agent""shell""http""chain""phone_action"spec?trigger*cron {type, expr, tz}, at {type, at}, interval {type, every_s}, event {type, trigger_id} or after {type, schedule_id, on}.
target*host {type, device_id}, tags {type, tags}, any, cloud or cloud_vm {type, project_id}.
failover?array<array<string>>native?booleanpolicy?Approval (never, always, outside quiet hours), quiet hours, budgets per run and per day (micro-USD) and the hourly run limit.
misfire?string"skip""once""all_within"misfire_window_min?integeroverlap?string"skip""queue""kill"timeout_s?integerretries?integerretry_backoff_s?integerlate_after_s?integeralert_on_fail?booleantemplate?stringcommand_hash?stringnext_run_at?stringdate-timelast_run_at?stringdate-timeupcoming*array<>approvals?array<>created_at?stringdate-timeupdated_at?stringdate-timecurl -X POST 'https://ai.codai.ro/v1/schedules' \ -H 'Content-Type: application/json' \ -d '{ "name": "string", "kind": "agent", "spec": {}, "trigger": {}}'{ "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", "name": "string", "description": "string", "enabled": true, "kind": "agent", "spec": {}, "trigger": {}, "target": {}, "failover": [ [ "string" ] ], "native": true, "policy": {}, "misfire": "skip", "misfire_window_min": 0, "overlap": "skip", "timeout_s": 0, "retries": 0, "retry_backoff_s": 0, "late_after_s": 0, "alert_on_fail": true, "template": "string", "command_hash": "string", "next_run_at": "2019-08-24T14:15:22Z", "last_run_at": "2019-08-24T14:15:22Z", "upcoming": [ "2019-08-24T14:15:22Z" ], "approvals": [ { "device_id": "3bafab7b-4400-4bcf-8e6e-09f954699940", "command_hash": "string", "approved_at": "2019-08-24T14:15:22Z" } ], "created_at": "2019-08-24T14:15:22Z", "updated_at": "2019-08-24T14:15:22Z"}bearerAuthAuthorizationBearer <codai_…>A codai API key (codai_ prefix). Ephemeral tokens from POST /v1/tokens are accepted only by the media surfaces matching their scope (/v1/realtime, /v1/audio/*, /v1/embeddings).
x-request-id?stringClient correlation id; echoed back as x-codai-trace-id and persisted on the usage row.
length <= 128application/json- body
text?stringlength <= 200trigger?tz?string"Europe/Bucharest"OK.
application/json- response
ok*booleanreason?string"not_understood""invalid"trigger?next_runs?array<>dst_warning?booleancurl -X POST 'https://ai.codai.ro/v1/schedules/preview' \ -H 'Content-Type: application/json' \ -d '{}'{ "ok": true, "reason": "not_understood", "trigger": {}, "next_runs": [ "2019-08-24T14:15:22Z" ], "dst_warning": true}bearerAuthAuthorizationBearer <codai_…>A codai API key (codai_ prefix). Ephemeral tokens from POST /v1/tokens are accepted only by the media surfaces matching their scope (/v1/realtime, /v1/audio/*, /v1/embeddings).
x-request-id?stringClient correlation id; echoed back as x-codai-trace-id and persisted on the usage row.
length <= 128OK.
response?stringtext/event-streamcurl -X GET 'https://ai.codai.ro/v1/schedules/stream'"string"bearerAuthAuthorizationBearer <codai_…>A codai API key (codai_ prefix). Ephemeral tokens from POST /v1/tokens are accepted only by the media surfaces matching their scope (/v1/realtime, /v1/audio/*, /v1/embeddings).
id*stringSchedule id.
uuidx-request-id?stringClient correlation id; echoed back as x-codai-trace-id and persisted on the usage row.
length <= 128OK.
application/json- response
A scheduled task.
id*stringuuidname*stringlength <= 120description?stringenabled*booleankind*string"agent""shell""http""chain""phone_action"spec?trigger*cron {type, expr, tz}, at {type, at}, interval {type, every_s}, event {type, trigger_id} or after {type, schedule_id, on}.
target*host {type, device_id}, tags {type, tags}, any, cloud or cloud_vm {type, project_id}.
failover?array<array<string>>native?booleanpolicy?Approval (never, always, outside quiet hours), quiet hours, budgets per run and per day (micro-USD) and the hourly run limit.
misfire?string"skip""once""all_within"misfire_window_min?integeroverlap?string"skip""queue""kill"timeout_s?integerretries?integerretry_backoff_s?integerlate_after_s?integeralert_on_fail?booleantemplate?stringcommand_hash?stringnext_run_at?stringdate-timelast_run_at?stringdate-timeupcoming*array<>approvals?array<>created_at?stringdate-timeupdated_at?stringdate-timecurl -X GET 'https://ai.codai.ro/v1/schedules/497f6eca-6276-4993-bfeb-53cbbbba6f08'{ "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", "name": "string", "description": "string", "enabled": true, "kind": "agent", "spec": {}, "trigger": {}, "target": {}, "failover": [ [ "string" ] ], "native": true, "policy": {}, "misfire": "skip", "misfire_window_min": 0, "overlap": "skip", "timeout_s": 0, "retries": 0, "retry_backoff_s": 0, "late_after_s": 0, "alert_on_fail": true, "template": "string", "command_hash": "string", "next_run_at": "2019-08-24T14:15:22Z", "last_run_at": "2019-08-24T14:15:22Z", "upcoming": [ "2019-08-24T14:15:22Z" ], "approvals": [ { "device_id": "3bafab7b-4400-4bcf-8e6e-09f954699940", "command_hash": "string", "approved_at": "2019-08-24T14:15:22Z" } ], "created_at": "2019-08-24T14:15:22Z", "updated_at": "2019-08-24T14:15:22Z"}bearerAuthAuthorizationBearer <codai_…>A codai API key (codai_ prefix). Ephemeral tokens from POST /v1/tokens are accepted only by the media surfaces matching their scope (/v1/realtime, /v1/audio/*, /v1/embeddings).
id*stringSchedule id.
uuidx-request-id?stringClient correlation id; echoed back as x-codai-trace-id and persisted on the usage row.
length <= 128application/json- body
[key: string]?anyOK.
application/json- response
A scheduled task.
id*stringuuidname*stringlength <= 120description?stringenabled*booleankind*string"agent""shell""http""chain""phone_action"spec?trigger*cron {type, expr, tz}, at {type, at}, interval {type, every_s}, event {type, trigger_id} or after {type, schedule_id, on}.
target*host {type, device_id}, tags {type, tags}, any, cloud or cloud_vm {type, project_id}.
failover?array<array<string>>native?booleanpolicy?Approval (never, always, outside quiet hours), quiet hours, budgets per run and per day (micro-USD) and the hourly run limit.
misfire?string"skip""once""all_within"misfire_window_min?integeroverlap?string"skip""queue""kill"timeout_s?integerretries?integerretry_backoff_s?integerlate_after_s?integeralert_on_fail?booleantemplate?stringcommand_hash?stringnext_run_at?stringdate-timelast_run_at?stringdate-timeupcoming*array<>approvals?array<>created_at?stringdate-timeupdated_at?stringdate-timecurl -X PATCH 'https://ai.codai.ro/v1/schedules/497f6eca-6276-4993-bfeb-53cbbbba6f08' \ -H 'Content-Type: application/json' \ -d '{}'{ "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", "name": "string", "description": "string", "enabled": true, "kind": "agent", "spec": {}, "trigger": {}, "target": {}, "failover": [ [ "string" ] ], "native": true, "policy": {}, "misfire": "skip", "misfire_window_min": 0, "overlap": "skip", "timeout_s": 0, "retries": 0, "retry_backoff_s": 0, "late_after_s": 0, "alert_on_fail": true, "template": "string", "command_hash": "string", "next_run_at": "2019-08-24T14:15:22Z", "last_run_at": "2019-08-24T14:15:22Z", "upcoming": [ "2019-08-24T14:15:22Z" ], "approvals": [ { "device_id": "3bafab7b-4400-4bcf-8e6e-09f954699940", "command_hash": "string", "approved_at": "2019-08-24T14:15:22Z" } ], "created_at": "2019-08-24T14:15:22Z", "updated_at": "2019-08-24T14:15:22Z"}bearerAuthAuthorizationBearer <codai_…>A codai API key (codai_ prefix). Ephemeral tokens from POST /v1/tokens are accepted only by the media surfaces matching their scope (/v1/realtime, /v1/audio/*, /v1/embeddings).
id*stringSchedule id.
uuidx-request-id?stringClient correlation id; echoed back as x-codai-trace-id and persisted on the usage row.
length <= 128Done, no content.
curl -X DELETE 'https://ai.codai.ro/v1/schedules/497f6eca-6276-4993-bfeb-53cbbbba6f08'bearerAuthAuthorizationBearer <codai_…>A codai API key (codai_ prefix). Ephemeral tokens from POST /v1/tokens are accepted only by the media surfaces matching their scope (/v1/realtime, /v1/audio/*, /v1/embeddings).
id*stringSchedule id.
uuidx-request-id?stringClient correlation id; echoed back as x-codai-trace-id and persisted on the usage row.
length <= 128Accepted.
application/json- response
queued*booleancurl -X POST 'https://ai.codai.ro/v1/schedules/497f6eca-6276-4993-bfeb-53cbbbba6f08/run'{ "queued": true}bearerAuthAuthorizationBearer <codai_…>A codai API key (codai_ prefix). Ephemeral tokens from POST /v1/tokens are accepted only by the media surfaces matching their scope (/v1/realtime, /v1/audio/*, /v1/embeddings).
id*stringSchedule id.
uuidx-request-id?stringClient correlation id; echoed back as x-codai-trace-id and persisted on the usage row.
length <= 128OK.
application/json- response
runs*array<>curl -X GET 'https://ai.codai.ro/v1/schedules/497f6eca-6276-4993-bfeb-53cbbbba6f08/runs'{ "runs": [ { "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", "schedule_id": "8929bb67-0da1-406c-99d2-5447376a4f58", "scheduled_for": "2019-08-24T14:15:22Z", "state": "pending", "attempt": 0, "device_id": "3bafab7b-4400-4bcf-8e6e-09f954699940", "started_at": "2019-08-24T14:15:22Z", "finished_at": "2019-08-24T14:15:22Z", "exit_code": 0, "cost_micro_usd": 0, "log_tail": "string", "session_id": "1ffd059c-17ea-40a8-8aef-70fd0307db82", "error": "string", "created_at": "2019-08-24T14:15:22Z" } ]}bearerAuthAuthorizationBearer <codai_…>A codai API key (codai_ prefix). Ephemeral tokens from POST /v1/tokens are accepted only by the media surfaces matching their scope (/v1/realtime, /v1/audio/*, /v1/embeddings).
id*stringSchedule id.
uuidx-request-id?stringClient correlation id; echoed back as x-codai-trace-id and persisted on the usage row.
length <= 128x-codai-device*stringStable device UUID. Registers the device on first use (name/platform from x-codai-device-name / x-codai-device-platform) and selects the shared-sessions protocol.
uuidapplication/json- body
command_hash*string^[0-9a-f]{64}$OK.
application/json- response
approved*booleandevice_id*stringuuidcurl -X POST 'https://ai.codai.ro/v1/schedules/497f6eca-6276-4993-bfeb-53cbbbba6f08/approve-command' \ -H 'x-codai-device: 497f6eca-6276-4993-bfeb-53cbbbba6f08' \ -H 'Content-Type: application/json' \ -d '{ "command_hash": "string"}'{ "approved": true, "device_id": "3bafab7b-4400-4bcf-8e6e-09f954699940"}bearerAuthAuthorizationBearer <codai_…>A codai API key (codai_ prefix). Ephemeral tokens from POST /v1/tokens are accepted only by the media surfaces matching their scope (/v1/realtime, /v1/audio/*, /v1/embeddings).
limit?integer1 <= value <= 20050x-request-id?stringClient correlation id; echoed back as x-codai-trace-id and persisted on the usage row.
length <= 128OK.
application/json- response
runs*array<>curl -X GET 'https://ai.codai.ro/v1/schedule-runs'{ "runs": [ { "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", "schedule_id": "8929bb67-0da1-406c-99d2-5447376a4f58", "scheduled_for": "2019-08-24T14:15:22Z", "state": "pending", "attempt": 0, "device_id": "3bafab7b-4400-4bcf-8e6e-09f954699940", "started_at": "2019-08-24T14:15:22Z", "finished_at": "2019-08-24T14:15:22Z", "exit_code": 0, "cost_micro_usd": 0, "log_tail": "string", "session_id": "1ffd059c-17ea-40a8-8aef-70fd0307db82", "error": "string", "created_at": "2019-08-24T14:15:22Z" } ]}bearerAuthAuthorizationBearer <codai_…>A codai API key (codai_ prefix). Ephemeral tokens from POST /v1/tokens are accepted only by the media surfaces matching their scope (/v1/realtime, /v1/audio/*, /v1/embeddings).
id*stringRun id.
uuidx-request-id?stringClient correlation id; echoed back as x-codai-trace-id and persisted on the usage row.
length <= 128application/json- body
approve*booleanOK.
application/json- response
One execution of a schedule.
id*stringuuidschedule_id*stringuuidscheduled_for*stringdate-timestate*string"pending""awaiting_approval""claimed""running""succeeded""failed""timed_out""skipped""cancelled"attempt*integerdevice_id?stringuuidstarted_at?stringdate-timefinished_at?stringdate-timeexit_code?integercost_micro_usd?integerlog_tail?stringsession_id?stringuuiderror?stringcreated_at?stringdate-timecurl -X POST 'https://ai.codai.ro/v1/schedule-runs/497f6eca-6276-4993-bfeb-53cbbbba6f08/decision' \ -H 'Content-Type: application/json' \ -d '{ "approve": true}'{ "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", "schedule_id": "8929bb67-0da1-406c-99d2-5447376a4f58", "scheduled_for": "2019-08-24T14:15:22Z", "state": "pending", "attempt": 0, "device_id": "3bafab7b-4400-4bcf-8e6e-09f954699940", "started_at": "2019-08-24T14:15:22Z", "finished_at": "2019-08-24T14:15:22Z", "exit_code": 0, "cost_micro_usd": 0, "log_tail": "string", "session_id": "1ffd059c-17ea-40a8-8aef-70fd0307db82", "error": "string", "created_at": "2019-08-24T14:15:22Z"}bearerAuthAuthorizationBearer <codai_…>A codai API key (codai_ prefix). Ephemeral tokens from POST /v1/tokens are accepted only by the media surfaces matching their scope (/v1/realtime, /v1/audio/*, /v1/embeddings).
id*stringRun id.
uuidx-request-id?stringClient correlation id; echoed back as x-codai-trace-id and persisted on the usage row.
length <= 128x-codai-device*stringStable device UUID. Registers the device on first use (name/platform from x-codai-device-name / x-codai-device-platform) and selects the shared-sessions protocol.
uuidapplication/json- body
attempt*integer1 <= valuelog?stringlength <= 16384Done, no content.
curl -X POST 'https://ai.codai.ro/v1/schedule-runs/497f6eca-6276-4993-bfeb-53cbbbba6f08/heartbeat' \ -H 'x-codai-device: 497f6eca-6276-4993-bfeb-53cbbbba6f08' \ -H 'Content-Type: application/json' \ -d '{ "attempt": 1}'bearerAuthAuthorizationBearer <codai_…>A codai API key (codai_ prefix). Ephemeral tokens from POST /v1/tokens are accepted only by the media surfaces matching their scope (/v1/realtime, /v1/audio/*, /v1/embeddings).
id*stringRun id.
uuidx-request-id?stringClient correlation id; echoed back as x-codai-trace-id and persisted on the usage row.
length <= 128x-codai-device*stringStable device UUID. Registers the device on first use (name/platform from x-codai-device-name / x-codai-device-platform) and selects the shared-sessions protocol.
uuidapplication/json- body
attempt*integer1 <= valueok*booleanexit_code?integererror?stringlength <= 4000log_tail?stringlength <= 65536cost_micro_usd?integer0 <= valuesession_id?stringuuidtimed_out?booleanOK.
application/json- response
One execution of a schedule.
id*stringuuidschedule_id*stringuuidscheduled_for*stringdate-timestate*string"pending""awaiting_approval""claimed""running""succeeded""failed""timed_out""skipped""cancelled"attempt*integerdevice_id?stringuuidstarted_at?stringdate-timefinished_at?stringdate-timeexit_code?integercost_micro_usd?integerlog_tail?stringsession_id?stringuuiderror?stringcreated_at?stringdate-timecurl -X POST 'https://ai.codai.ro/v1/schedule-runs/497f6eca-6276-4993-bfeb-53cbbbba6f08/result' \ -H 'x-codai-device: 497f6eca-6276-4993-bfeb-53cbbbba6f08' \ -H 'Content-Type: application/json' \ -d '{ "attempt": 1, "ok": true}'{ "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", "schedule_id": "8929bb67-0da1-406c-99d2-5447376a4f58", "scheduled_for": "2019-08-24T14:15:22Z", "state": "pending", "attempt": 0, "device_id": "3bafab7b-4400-4bcf-8e6e-09f954699940", "started_at": "2019-08-24T14:15:22Z", "finished_at": "2019-08-24T14:15:22Z", "exit_code": 0, "cost_micro_usd": 0, "log_tail": "string", "session_id": "1ffd059c-17ea-40a8-8aef-70fd0307db82", "error": "string", "created_at": "2019-08-24T14:15:22Z"}bearerAuthAuthorizationBearer <codai_…>A codai API key (codai_ prefix). Ephemeral tokens from POST /v1/tokens are accepted only by the media surfaces matching their scope (/v1/realtime, /v1/audio/*, /v1/embeddings).
x-request-id?stringClient correlation id; echoed back as x-codai-trace-id and persisted on the usage row.
length <= 128OK.
application/json- response
hosts*array<>curl -X GET 'https://ai.codai.ro/v1/scheduler/hosts'{ "hosts": [ { "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", "name": "string", "platform": "string", "os": "string", "arch": "string", "host_kind": "string", "tags": [ "string" ], "capabilities": [ "string" ], "online": true, "last_seen_at": "2019-08-24T14:15:22Z", "app_version": "string" } ]}bearerAuthAuthorizationBearer <codai_…>A codai API key (codai_ prefix). Ephemeral tokens from POST /v1/tokens are accepted only by the media surfaces matching their scope (/v1/realtime, /v1/audio/*, /v1/embeddings).
id*stringDevice id of the host.
uuidx-request-id?stringClient correlation id; echoed back as x-codai-trace-id and persisted on the usage row.
length <= 128application/json- body
name?stringlength <= 120tags?array<>items <= 16host_kind?string"pc""phone""watch""vm""cloud"os?string"windows""macos""linux""android""wearos""ios"arch?stringlength <= 20OK.
application/json- response
[key: string]?anycurl -X PATCH 'https://ai.codai.ro/v1/scheduler/hosts/497f6eca-6276-4993-bfeb-53cbbbba6f08' \ -H 'Content-Type: application/json' \ -d '{}'{}bearerAuthAuthorizationBearer <codai_…>A codai API key (codai_ prefix). Ephemeral tokens from POST /v1/tokens are accepted only by the media surfaces matching their scope (/v1/realtime, /v1/audio/*, /v1/embeddings).
x-request-id?stringClient correlation id; echoed back as x-codai-trace-id and persisted on the usage row.
length <= 128x-codai-device*stringStable device UUID. Registers the device on first use (name/platform from x-codai-device-name / x-codai-device-platform) and selects the shared-sessions protocol.
uuidOK.
application/json- response
run*One execution of a schedule.
schedule*A scheduled task.
host_approved*booleancurl -X POST 'https://ai.codai.ro/v1/scheduler/claim' \ -H 'x-codai-device: 497f6eca-6276-4993-bfeb-53cbbbba6f08'{ "run": { "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", "schedule_id": "8929bb67-0da1-406c-99d2-5447376a4f58", "scheduled_for": "2019-08-24T14:15:22Z", "state": "pending", "attempt": 0, "device_id": "3bafab7b-4400-4bcf-8e6e-09f954699940", "started_at": "2019-08-24T14:15:22Z", "finished_at": "2019-08-24T14:15:22Z", "exit_code": 0, "cost_micro_usd": 0, "log_tail": "string", "session_id": "1ffd059c-17ea-40a8-8aef-70fd0307db82", "error": "string", "created_at": "2019-08-24T14:15:22Z" }, "schedule": { "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", "name": "string", "description": "string", "enabled": true, "kind": "agent", "spec": {}, "trigger": {}, "target": {}, "failover": [ [ "string" ] ], "native": true, "policy": {}, "misfire": "skip", "misfire_window_min": 0, "overlap": "skip", "timeout_s": 0, "retries": 0, "retry_backoff_s": 0, "late_after_s": 0, "alert_on_fail": true, "template": "string", "command_hash": "string", "next_run_at": "2019-08-24T14:15:22Z", "last_run_at": "2019-08-24T14:15:22Z", "upcoming": [ "2019-08-24T14:15:22Z" ], "approvals": [ { "device_id": "3bafab7b-4400-4bcf-8e6e-09f954699940", "command_hash": "string", "approved_at": "2019-08-24T14:15:22Z" } ], "created_at": "2019-08-24T14:15:22Z", "updated_at": "2019-08-24T14:15:22Z" }, "host_approved": true}Pending prompts
Ready-to-paste prompts that agents (or you) leave for a future chat — handoffs, dated follow-ups — with reminders and one-click launch on a device.
Transcripts
Record meetings and calls on any device, get a diarized Romanian/English transcript with word timings, then a summary, key points, actions and ready-to-run agent prompts.