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
| Field | Required | Description |
|---|---|---|
id | yes | Unique step identifier within this recipe. Used in artifact refs and param scoping. |
type | yes | Executor type. Must match a registered executor in step_executor. |
inputs | yes | Maps executor input slot names to artifact references. Keys must exactly match the executor's accepts. |
outputs | yes | Maps executor output slot names to artifact references. Keys must exactly match the executor's produces. |
param_keys | no | Array 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.