{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "https://artifacts.apis.io/crevio-co/json-schema/crevio-co-ai-task-request-schema.json",
  "title": "AiTaskRequest",
  "x-generated": "2026-11-04",
  "x-method": "derived",
  "x-generator": "derive-json-schema.py",
  "x-source": "openapi/crevio-co-openapi.json#/components/schemas/AiTaskRequest",
  "type": "object",
  "properties": {
    "name": {
      "type": "string"
    },
    "description": {
      "type": [
        "string",
        "null"
      ]
    },
    "kind": {
      "type": "string",
      "enum": [
        "agent",
        "script"
      ],
      "default": "agent",
      "description": "`agent` runs `prompt` as an agent turn. `script` runs `script` on the account's computer with no agent and no model credits, for runs that are the same deterministic steps every time; it takes no `prompt`. To switch kind, send the new `kind` with its field and `null` for the other."
    },
    "prompt": {
      "type": [
        "string",
        "null"
      ],
      "maxLength": 10000,
      "description": "What the agent does on each run. Required for `kind: agent`, must be absent for `kind: script`."
    },
    "success_criteria": {
      "type": [
        "string",
        "null"
      ],
      "maxLength": 2000,
      "description": "What done means for one run: the checkable outcomes a finished run must have produced (a post is live at its URL, the report reached #sales, every new order has a tracking number). Every run is shown them and must check its result against them before it reports. Outcomes, not steps; the steps belong in `prompt`."
    },
    "trigger_type": {
      "type": "string",
      "enum": [
        "immediate",
        "cron",
        "interval",
        "once",
        "event"
      ]
    },
    "cron_expression": {
      "type": [
        "string",
        "null"
      ]
    },
    "interval_seconds": {
      "type": [
        "integer",
        "null"
      ]
    },
    "scheduled_at": {
      "type": [
        "string",
        "null"
      ],
      "format": "date-time"
    },
    "timezone": {
      "type": "string"
    },
    "model_id": {
      "type": [
        "string",
        "null"
      ]
    },
    "agent": {
      "type": "string",
      "enum": [
        "business",
        "engineering"
      ],
      "description": "Which agent runs the task. Use `engineering` for pure code/build work on a site; defaults to `business`."
    },
    "condition_script": {
      "type": [
        "string",
        "null"
      ],
      "description": "Cheap pre-run gate for recurring tasks (`cron`/`interval`). Plain JavaScript run in a sandboxed isolate against the same `crevioApi.*` connector as the execute tool, BEFORE each scheduled run — no LLM, no credits. The task only runs when the script's last expression (or explicit `return`) is truthy; it skips on `false`/`null`. **Default to setting this whenever the task is \"act only when X\"** (new/unfulfilled/failed records, a threshold crossed, an unread inbox, a metric at zero) — without it the agent wakes and spends credits on every tick even when there's nothing to do. Only omit it for tasks that genuinely should run every tick (e.g. a scheduled report the user always wants). End with a boolean, e.g. `const r = await crevioApi.listOrders({ status: 'succeeded' }); r.data.some(o => o.fulfillment_status !== 'fulfilled')`. Errors fail open (the task runs). Ignored for non-recurring triggers."
    },
    "pre_run_script": {
      "type": [
        "string",
        "null"
      ]
    },
    "script": {
      "type": [
        "string",
        "null"
      ],
      "maxLength": 10000,
      "description": "JavaScript run on the account's computer on each run; its logs and return value become the run's summary. Required for `kind: script`, must be absent for `kind: agent`."
    },
    "approval_mode": {
      "type": "string",
      "enum": [
        "autonomous",
        "supervised",
        "read_only"
      ]
    },
    "expires_at": {
      "type": [
        "string",
        "null"
      ],
      "format": "date-time"
    },
    "active": {
      "type": "boolean"
    },
    "visibility": {
      "type": "string",
      "enum": [
        "account",
        "personal"
      ]
    },
    "max_runs_per_day": {
      "type": [
        "integer",
        "null"
      ],
      "minimum": 1,
      "maximum": 1440,
      "description": "Event tasks only: at most this many runs started by events per calendar day, in the account's time zone. Every further event that day is recorded as a skipped run (`skip_reason: rate_limited`) and starts nothing, webhook deliveries included. Test runs don't count. Set it whenever the user names a daily cap; `null` removes it."
    },
    "min_interval_seconds": {
      "type": [
        "integer",
        "null"
      ],
      "minimum": 1,
      "maximum": 604800,
      "description": "Event tasks only: cooldown after a run started by an event. An event within this many seconds of that run is recorded as a skipped run (`skip_reason: rate_limited`) and starts nothing. Set it whenever the user says \"at most once every N minutes\"; `null` removes it."
    },
    "slack_sender_name": {
      "type": [
        "string",
        "null"
      ],
      "maxLength": 80,
      "description": "The name Slack shows on the results this task posts, in place of Crevio or the task's bot. Set it only when the user names one; `null` removes it."
    },
    "delivery_methods": {
      "type": "array",
      "items": {
        "type": "string",
        "enum": [
          "notification",
          "email",
          "telegram",
          "discord",
          "slack"
        ]
      },
      "default": [
        "notification",
        "email"
      ],
      "description": "Where each run's result is delivered. Omit it to get the default, in-app notification plus email; set it only when the user asked for a specific channel. `[]` delivers nowhere."
    },
    "event_conditions": {
      "type": [
        "object",
        "null"
      ],
      "additionalProperties": true,
      "description": "Event tasks only: what starts a run. `event_type` is one event from GET /v1/events. To run after another task finishes, use `{event_type: \"task_run.completed\", after_task_id: \"task_...\"}` (or `task_run.failed` to run when it fails): each real run of that task that finishes starts this one, and the run receives the finished run (id, summary, status) as `event.data.object`. Test runs start nothing. A chain that loops back on itself or runs longer than 5 tasks is refused. `email_message.*` events also take `inbox_id`; `external.slack.*` events take `channel_id`, `from_user_id`, `reaction` and `channel_type`; `external.discord.*` events (`message`, `mention`, `reaction_added`) take `channel_id`, `from_user_id`, `emoji` and `guild_id`."
    },
    "site_id": {
      "type": "string",
      "description": "Site this task works on (`site_...`); its repo is mounted as the run's workspace. Defaults to the account's default working site."
    }
  }
}