ImageStep · Schema

PresetData

A preset: a named, versioned list of steps, each an L1 op or a processing-registry step. GET returns the export shape; POST /api/v1/presets/import takes it back.

AutomationAIOpsDeterministic OpsSDKCLI

Properties

Name Type Description
id string Preset id (`pre_…`; a built-in's starts with `builtin-`). A job's `presetId` takes it, the slug, or either with `@version`.
name string Display name (required on create).
slug string URL-safe handle, unique per account: lowercase letters, digits and hyphens. Generated from the name when absent (a numeric suffix keeps it unique); one you send must be free. `builtin-` is reserved.
description string Free text for people; not run. `""` on a PUT empties it.
subjects array What has to look the same every time: each subject is `{name, referenceAssetIds, descriptor}`, at most 4 of them. The images (max 4 across all subjects, your own, status DONE) ride along on the preset
steps array The steps, run in order. Each is `{op, model?, prompt?, parameters?}` (an op from GET /api/v1/ops) or `{operation, params}` (a processing-registry key, for what no op covers). Checked when written: a
version integer Starts at 1 and goes up whenever `steps` or `subjects` change; a name, description or slug edit is not a version. Run or read an earlier one as `slug@version` / `?version=N`.
versions array Superseded versions, oldest first. Present in exports so an import replays the same history. GET /api/v1/presets leaves it off unless you ask for `?includeVersions=true` — a list row does not need eve
versionCount integer How many versions are on record: the current one plus every superseded one. Always present on a read, whether or not `versions` is, so a list reader can tell a preset with history from one without fet
createdAt string When the preset was created
updatedAt string When the preset was last saved, a rename included — the order your own rows are listed in. On an earlier version read as `slug@N`, when that version was saved.
builtIn boolean Whether this is a built-in preset (read-only)
warnings array What these steps say that is legal, will run, and is probably not what was meant (imagestep#416): a format a later step shadows, a step the one before it already did. Advisory — the preset was saved.
usage object How often this preset has run and when it last did, over the jobs still on record (imagestep#423). Present on reads — GET /api/v1/presets and GET /api/v1/presets/{slug} — and left off a write, which a
View JSON Schema on GitHub

JSON Schema

imagestep-dev-preset-data-schema.json Raw ↑
{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "https://artifacts.apis.io/imagestep-dev/json-schema/imagestep-dev-preset-data-schema.json",
  "title": "PresetData",
  "description": "A preset: a named, versioned list of steps, each an L1 op or a processing-registry step. GET returns the export shape; POST /api/v1/presets/import takes it back.",
  "x-generated": "2026-11-12",
  "x-method": "derived",
  "x-generator": "derive-json-schema.py",
  "x-source": "openapi/imagestep-dev-openapi.json#/components/schemas/PresetData",
  "type": "object",
  "properties": {
    "id": {
      "type": "string",
      "description": "Preset id (`pre_…`; a built-in's starts with `builtin-`). A job's `presetId` takes it, the slug, or either with `@version`.",
      "readOnly": true
    },
    "name": {
      "type": "string",
      "description": "Display name (required on create)."
    },
    "slug": {
      "type": "string",
      "description": "URL-safe handle, unique per account: lowercase letters, digits and hyphens. Generated from the name when absent (a numeric suffix keeps it unique); one you send must be free. `builtin-` is reserved."
    },
    "description": {
      "type": "string",
      "description": "Free text for people; not run. `\"\"` on a PUT empties it."
    },
    "subjects": {
      "type": "array",
      "description": "What has to look the same every time: each subject is `{name, referenceAssetIds, descriptor}`, at most 4 of them. The images (max 4 across all subjects, your own, status DONE) ride along on the preset's generate / edit step and pin the geometry; the descriptor expands into its prompt wherever you write `{{subject.<name>}}`. A preset with subjects needs a generate or edit step.",
      "items": {
        "$ref": "#/$defs/Subject"
      }
    },
    "steps": {
      "type": "array",
      "description": "The steps, run in order. Each is `{op, model?, prompt?, parameters?}` (an op from GET /api/v1/ops) or `{operation, params}` (a processing-registry key, for what no op covers). Checked when written: a parameter outside its op's contract is 400 invalid_param on `steps[i].parameters.<name>`. Adjacent deterministic steps run as one `process` pass and each AI step as its op's own job; those are the preset's segments. One segment runs as that job; more than one — an AI step beside other steps, or several AI steps — runs as one `chain` job, each item walking the segments in order with the output of one as the input of the next.",
      "items": {
        "$ref": "#/$defs/PresetStep"
      }
    },
    "version": {
      "type": "integer",
      "format": "int32",
      "description": "Starts at 1 and goes up whenever `steps` or `subjects` change; a name, description or slug edit is not a version. Run or read an earlier one as `slug@version` / `?version=N`."
    },
    "versions": {
      "type": "array",
      "description": "Superseded versions, oldest first. Present in exports so an import replays the same history. GET /api/v1/presets leaves it off unless you ask for `?includeVersions=true` — a list row does not need every snapshot of every preset, and `versionCount` says whether there is any history to read.",
      "items": {
        "$ref": "#/$defs/PresetVersion"
      }
    },
    "versionCount": {
      "type": "integer",
      "format": "int32",
      "description": "How many versions are on record: the current one plus every superseded one. Always present on a read, whether or not `versions` is, so a list reader can tell a preset with history from one without fetching it.",
      "readOnly": true
    },
    "createdAt": {
      "type": "string",
      "format": "date-time",
      "description": "When the preset was created",
      "readOnly": true
    },
    "updatedAt": {
      "type": "string",
      "format": "date-time",
      "description": "When the preset was last saved, a rename included — the order your own rows are listed in. On an earlier version read as `slug@N`, when that version was saved.",
      "readOnly": true
    },
    "builtIn": {
      "type": "boolean",
      "description": "Whether this is a built-in preset (read-only)"
    },
    "warnings": {
      "type": "array",
      "description": "What these steps say that is legal, will run, and is probably not what was meant (imagestep#416): a format a later step shadows, a step the one before it already did. Advisory — the preset was saved. Derived, never stored: a write answers with the findings about what it just saved, and POST /api/v1/jobs?dryRun=true recomputes them for any preset. A step whose model is being retired, or was, also says so on GET /api/v1/presets/{slug} (model_deprecated, model_replaced): a version keeps the id it was written with. What could not run at all was refused instead, 400 invalid_param naming the step.",
      "items": {
        "$ref": "#/$defs/StepWarning"
      },
      "readOnly": true
    },
    "usage": {
      "$ref": "#/$defs/PresetUsage",
      "description": "How often this preset has run and when it last did, over the jobs still on record (imagestep#423). Present on reads — GET /api/v1/presets and GET /api/v1/presets/{slug} — and left off a write, which answers about what it just saved. Derived, never stored.",
      "readOnly": true
    }
  },
  "$defs": {
    "Details": {
      "type": "object",
      "description": "The model a retirement warning is about, and what replaces it",
      "properties": {
        "model": {
          "type": "string",
          "description": "The model id as the request or the step names it"
        },
        "retireAt": {
          "type": "string",
          "description": "The day this service switches, 00:00 UTC, an ISO date"
        },
        "successor": {
          "type": "string",
          "description": "What it runs as from `retireAt`; absent when it is refused from then"
        },
        "successorCostPerItem": {
          "type": "integer",
          "format": "int64",
          "description": "Credits per item on the successor at these parameters, mapped — what the same request costs from `retireAt`. On a dry run; a preset write or read leaves it out."
        }
      }
    },
    "PresetStep": {
      "type": "object",
      "description": "A preset step: either an L1 op from GET /api/v1/ops — {op, model?, prompt?, parameters?} — or a processing-registry step — {operation, params} — for what no op covers. Never both.",
      "properties": {
        "op": {
          "type": "string",
          "description": "An op from GET /api/v1/ops (kind ai or deterministic)."
        },
        "model": {
          "type": "string",
          "description": "AI steps: the model; the op's default when absent."
        },
        "prompt": {
          "type": "string",
          "description": "AI steps: the prompt. {{subject.<name>}} expands to that subject's descriptor."
        },
        "parameters": {
          "type": "object",
          "additionalProperties": {},
          "description": "The op's parameters. A deterministic op's are checked against its catalogue contract when the steps are written, and so are `analyze`'s bounds; an AI image op's go to the model as sent."
        },
        "operation": {
          "type": "string",
          "description": "A processing-registry key (deterministic only), for steps no op covers."
        },
        "params": {
          "type": "object",
          "description": "That registry step's arguments."
        }
      }
    },
    "PresetUsage": {
      "type": "object",
      "description": "How often this preset has been run, over the jobs still on record — job records expire with the assets they produced, so this is the retention window and not all time. Read-only and derived.",
      "properties": {
        "runs": {
          "type": "integer",
          "format": "int64",
          "description": "Jobs that ran this preset, at any version, within the retention window."
        },
        "lastRunAt": {
          "type": "string",
          "format": "date-time",
          "description": "When the most recent of them was submitted."
        }
      }
    },
    "PresetVersion": {
      "type": "object",
      "description": "A superseded version of a preset: its steps and subjects as they were, and when that version was saved.",
      "properties": {
        "version": {
          "type": "integer",
          "format": "int32",
          "description": "The version number; `slug@version` runs and reads exactly this."
        },
        "steps": {
          "type": "array",
          "description": "The steps as that version had them.",
          "items": {
            "$ref": "#/$defs/PresetStep"
          }
        },
        "subjects": {
          "type": "array",
          "description": "The subjects as that version had them.",
          "items": {
            "$ref": "#/$defs/Subject"
          }
        },
        "updatedAt": {
          "type": "string",
          "format": "date-time",
          "description": "When that version was saved."
        }
      }
    },
    "StepWarning": {
      "type": "object",
      "description": "An advisory finding about a list of steps, or about the model a job runs on: legal, and probably not what was meant",
      "properties": {
        "code": {
          "type": "string",
          "description": "Machine-readable finding code from a closed set; the table is /docs/presets#warnings"
        },
        "message": {
          "type": "string",
          "description": "The finding in one sentence, naming the steps by index"
        },
        "steps": {
          "type": "array",
          "description": "The step indexes the finding is about, in order — the redundant one first. Absent when the finding is about the job's own model rather than a step.",
          "items": {
            "type": "integer",
            "format": "int32"
          }
        },
        "details": {
          "$ref": "#/$defs/Details",
          "description": "The finding as data, for a code that has some: `model_deprecated` and `model_replaced` say which model, when it switches, what it switches to and what an item costs there"
        }
      }
    },
    "Subject": {
      "type": "object",
      "description": "A recurring character, product or location: reference images plus the locked words for it.",
      "properties": {
        "name": {
          "type": "string",
          "description": "Lowercase handle (`[a-z0-9][a-z0-9_-]{0,39}`, unique among the subjects), referenced in a prompt as {{subject.<name>}}."
        },
        "referenceAssetIds": {
          "type": "array",
          "description": "Your own DONE asset ids showing this subject. They pin the geometry.",
          "items": {
            "type": "string"
          }
        },
        "descriptor": {
          "type": "string",
          "description": "The locked description — colour, material, markings — at most 300 characters. Text pins what an image cannot show."
        }
      }
    }
  }
}

Work with this as data

Every JSON Schema here is available over the APIs.io API and to AI agents over MCP.

MCP server

One button, every client — Claude, Cursor, VS Code and the rest.

https://apis.io/mcp

Tools for schemas

4 MCP tools reach this
  • find_json_schemasBrowse and filter every JSON Schema in the catalog.
  • apis_io_searchSTART HERE — APIs, providers and tags for one query, each with its total.
  • resolveTurn a domain, URL or GitHub org into the provider it belongs to.
  • find_cohortsEvery scored population of providers in the catalog.
All 92 tools →

Call it yourself

curl for this page
This JSON Schema
curl "https://apis.io/api/v1/json-schemas/imagestep-dev-preset-data"
All schemas
curl "https://apis.io/api/v1/json-schemas?limit=25"

Calls without X-API-Key need no key. Calls with it need a paid plan — get a key.

Get an API key

Free tier, no form to fill in. Signing in shares your email address with us — we store it to create your key and to recognise you if you sign in with another provider. See our Privacy Policy and Terms.

A second provider on the same verified email joins the account you already have.