Writing a Recipe
This walkthrough builds a real recipe step by step: reproject a point cloud, then build a Potree tileset.
1. Decide what the pipeline should do
Goal: take a raw LAS file in a local coordinate system, reproject it to Web Mercator (EPSG:3857), and produce a Potree-compatible tileset for web visualization.
Steps needed:
REPROJECT_LAS— transform the coordinate systemBUILD_POTREE— produce the tileset
2. Check executor contracts
From the executor reference:
| Type | Accepts | Produces | Params |
|---|---|---|---|
REPROJECT_LAS | input_las: las | output_las: las | source_epsg, target_epsg |
BUILD_POTREE | input_las: las | output_potree: potree | none |
3. Plan artifact flow
- Job input:
job:input_las(the raw LAS file) - After reproject:
step:reproject.output_las - After build:
step:build_potree.output_potree
4. Write the step list
json
"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_potree",
"type": "BUILD_POTREE",
"inputs": { "input_las": "step:reproject.output_las" },
"outputs": { "output_potree": "step:build_potree.output_potree" }
}
]Key checks:
input_lasinREPROJECT_LAS.inputsmatches the executor'sacceptsslot nameoutput_lasinREPROJECT_LAS.outputsmatches the executor'sproducesslot namebuild_potreereads fromstep:reproject.output_las— the valuereprojectwrote
5. Add an on_exit hook (optional but recommended)
Add a CALL_WEBHOOK to notify when the job finishes. It needs to wait for something — use the last artifact produced:
json
"on_exit": {
"id": "call_webhook",
"type": "CALL_WEBHOOK",
"inputs": { "waits_for": "step:build_potree.output_potree" },
"param_keys": ["webhook_url"]
}6. Assemble the full recipe
json
{
"name": "reproject-and-build-potree",
"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_potree",
"type": "BUILD_POTREE",
"inputs": { "input_las": "step:reproject.output_las" },
"outputs": { "output_potree": "step:build_potree.output_potree" }
}
],
"on_exit": {
"id": "call_webhook",
"type": "CALL_WEBHOOK",
"inputs": { "waits_for": "step:build_potree.output_potree" },
"param_keys": ["webhook_url"]
}
}
}7. Submit a job using this recipe
bash
curl -X POST https://dev.mapprism.com/ordo/jobs \
-H "Authorization: Bearer <API_TOKEN>" \
-H "Content-Type: application/json" \
-d '{
"recipe": {
"name": "reproject-and-build-potree",
"version": "1.0.0",
"definition": { ... }
},
"inputs": {
"job:input_las": {
"type": "las",
"uri": "development/survey/dataset.las",
"hash": "abc123"
}
},
"params": {
"reproject": {
"source_epsg": "EPSG:2271",
"target_epsg": "EPSG:3857"
},
"call_webhook": {
"webhook_url": "https://myapp.example.com/hooks/processing-done"
}
},
"outputs": {
"step:build_potree.output_potree": {
"path": "development/results/survey/potree"
}
}
}'Response:
json
{ "id": 7 }Poll with GET /ordo/jobs/7 until job.status is success or failed.