Skip to content

Recipe Anatomy

A recipe is a JSON object with a name, version, and definition. The definition contains the step list and an optional on_exit hook.

Full shape

json
{
  "name": "my-pipeline",
  "version": "1.0.0",
  "definition": {
    "recipe": [
      {
        "id": "reproject",
        "type": "REPROJECT_LAS",
        "inputs":  { "input_las": "job:input_las" },
        "outputs": { "output_las": "step:reproject.output_las" },
        "param_keys": ["source_epsg", "target_epsg"]
      },
      {
        "id": "build_ept",
        "type": "BUILD_EPT",
        "inputs":  { "input_las": "step:reproject.output_las" },
        "outputs": { "output_ept": "step:build_ept.output_ept" }
      }
    ],
    "on_exit": {
      "id": "call_webhook",
      "type": "CALL_WEBHOOK",
      "inputs": { "waits_for": "step:build_ept.output_ept" },
      "param_keys": ["webhook_url"]
    }
  }
}

Step fields

FieldRequiredDescription
idyesUnique step identifier within this recipe. Used in artifact refs and param scoping.
typeyesExecutor type. Must match a registered executor in step_executor.
inputsyesMaps executor input slot names to artifact references. Keys must exactly match the executor's accepts.
outputsyesMaps executor output slot names to artifact references. Keys must exactly match the executor's produces.
param_keysnoArray of param names this step requires at job submission time.

The on_exit hook

on_exit is a single step that runs after the main pipeline completes, regardless of success or failure. It follows the same step shape as recipe steps.

The canonical use is CALL_WEBHOOK: fire a notification once processing is done.

json
"on_exit": {
  "id": "call_webhook",
  "type": "CALL_WEBHOOK",
  "inputs": { "waits_for": "step:dataset_info.metadata" },
  "param_keys": ["webhook_url"]
}

See on-exit-hooks.md for details on webhook behavior.

Inline recipe vs recipe_id

When submitting a job, you can either provide a full inline recipe or reference an existing recipe by ID:

Inline (find-or-create by name+version):

json
{
  "recipe": {
    "name": "my-pipeline",
    "version": "1.0.0",
    "definition": { ... }
  },
  "inputs": { ... }
}

By ID:

json
{
  "recipe_id": 7,
  "inputs": { ... }
}

When using inline recipes, Ordo matches by name + version. If a matching recipe already exists in the database, it's reused and the provided definition is ignored. If it doesn't exist, it's created.