EmbodiFlowDocs
Get startedDataWorkflows and algorithmsTraining and deploymentDeveloper reference
  • Workflows and algorithms

Workflows

  • How workflows work
  • Build your own workflow
  • Runs and logs

Algorithms

  • Algorithm catalog
  • Write a custom algorithm

Algorithm developer guide

  • Your first algorithm
    • Standardize
    • Check
    • Transform
    • Enrich
    • Segment
    • Curate
    • Export
  • Image algorithms
  • Use your algorithm in a workflow
  • Interface reference
  • SDK reference
  • Command line
  • MCP tools
  • Troubleshooting

© 2026 EmbodiFlow

llms.txtOpenAPI JSON
  1. Workflows and algorithms
  2. Algorithm developer guide
  3. Interface reference

Interface reference

Everything an algorithm can declare: decorator arguments, features, parameters, semantic types, facts, resources, exit states and versions.

In a Python algorithm, the decorator and the Params dataclass in main.py are the interface. Everything else in the file is just the work. Keeping the two apart is what lets the platform show your ports in the editor, check workflow connections and propose version numbers, all without running your code.

When you save, the platform reads the interface statically and freezes it with the version as algorithm.yaml. At run time the SDK rebuilds the interface from the decorator and refuses to start if it differs from the frozen one (ALGORITHM_MANIFEST_DRIFT).

Decorator arguments and param(...) defaults must be literals: strings, numbers, booleans, lists, dicts and the SDK constructors Feature, Check, Input and param. Anything else is refused with ALGORITHM_FILE_INVALID, and the message names the line.
Beta. Custom algorithms and workflows are in the product and ready to try, but they haven't been through a full acceptance on real data yet. Expect some rough edges, and check results before you rely on them.

Decorator arguments

ArgumentRequiredRule
name, titleyesname is lowercase letters, digits and -, 2 to 63 long, starting with a letter. It is fixed for the algorithm's life. A team name may not start with ef- or embodiflow-.
descriptionnoShown in the library.
levelnocheck and enrich: recording (default) or episode.
readscheck at recording levelraw or recording (default).
inputsnoExtra features inputs: Input(requires=[…], optional=False). Names are lowercase letters, digits and _, up to 32 long, and not a data type name, a default port name or a run argument name.
featuresenrichAt least one Feature(...).
checkscheck; any category that writes checksCheck(id, title, description="").
labelssegmentThe label keys its episodes carry: {key: semantic type}.
requiresnoFacts the data must have. See below.
paramsnoA dataclass whose every field is param(default, …).
resourcesnoSee below.
requirementsnopip requirement strings. Binary wheels only. Locked at save.
retries, cachenoDefault: one retry on transient errors, cache on.
servicesnoBuilt-in algorithms only: ["vlm"].
privacynoBuilt-in algorithms only: "redacts" or "numbers_only".

You don't write a version in the code. When you save, the platform proposes the next version from what changed in the interface.

Data types

Ports carry one of eight data types, and a connection is only allowed between ports of the same type.

TypeWhat it is
rawOne recording's uploaded files.
recordingThe canonical recording: a LeRobot v3 tree plus meta/embodiflow/recording.json.
featuresNew values about a recording or its episodes.
checksJudgements, each with a status.
episodesTime ranges with a task text.
versionA dataset version.
selectionPer-episode decisions: keep, split, task.
artifactFiles to download.

Feature

A feature is declared as Feature(name, type, per, dtype=…, shape=…, unit=…, frame=…, names=…, source=…, describe=…).

FieldMeaning
nameA short name. The platform stores it under a name that belongs to your team.
typeA semantic type from the table below.
perframe, recording, episode or file.
dtypefloat32 (default), float64, int8, int16, int32, int64, uint8 or uint16.
shapeThe shape of one value. Array types have a fixed default shape.
unit, frameRequired for geometric types, except per file.
namesNames of the components, for example joint names.
sourcerecorded, imported, estimated, computed (default) or retargeted.
describeExtra description, for example {"targetRig": "tron2av3"} for a retargeted action.

Parameters

Parameters are the settings a workflow can change without touching your code. Every field of Params is param(default, minimum=…, maximum=…, enum=…, title=…, description=…, widget=…), and its type comes from the annotation: int, float, str, bool, or a list of strings, integers or floats.

A list field takes a literal list default and also items_enum, min_items and max_items. The widget tags takes free strings; multiselect needs items_enum. A workflow sets values in with, and the platform checks them against these limits.

Semantic types

A feature's semantic type tells the next step what the numbers mean; it's how the editor knows which outputs can feed an input that requires, say, keypoints3d.hand21. The registry is closed, and teams use these types as they are.

TypeMeaningShape or value
scalarOne number[1]
vectorNumbers[n]
label.boolYes or no labelbool
label.categoryOne of a declared setstring; describe.values
label.textFree textstring
spansTime ranges inside an episode or recordinglist of { startS, endS, label }
embeddingAn embedding vector[n]; describe.model
pose.se3Position and quaternion[7]: x y z qx qy qz qw; unit, frame
keypoints3d.hand2121 hand landmarks in 3D, MediaPipe order[63]; unit, frame
skeleton.hand2121 hand joints with a 6-DoF frame each, MediaPipe order[147] = 21 x (x y z qx qy qz qw); unit, frame
skeleton.body2222 body joints with a 6-DoF frame each, SMPL order (pelvis first)[154] = 22 x (x y z qx qy qz qw); unit, frame
keypoints2d2D image keypoints[2k]; frame is the camera
confidencePer-sample confidence from 0 to 1[n]
calibration.stereoRectified stereo extrinsics{ R[9], T[3] }
calibration.cam_imuCamera to IMU transform and time offset{ R[9], T[3], dtS }
depth.video16-bit depth video sidecarfile
mask.videoPer-frame mask videofile
video.previewLight browser preview copy of one camera video, same framesfile, embodiflow-preview/v1
ros2.mcapROS 2 MCAP file (TF tree, images, point clouds, markers)file
action.jointJoint-space action[n]; names
action.ee_poseEnd-effector action[7], or [8] with the gripper
jsonAny small JSONobject, at most 1 MiB; matched by requires only as name:<feature>

Facts and requires

Facts are what the platform knows about the data, derived from the data itself and never typed in by a person. Your code reads them as ctx.facts, and requires uses them to decide whether your algorithm applies at all.

FactTypeKnown from
kindrobot or humanThe project
formatstring: mcap, lerobot, video, or x-<team format>The upload
privacy_requiredboolThe recording profile
duration_snumberThe upload summary, then the recording, then the episode window
camerasintegerThe upload summary, then the recording
stereoboolThe recording: a stereo pair with intrinsics
imuboolThe recording: IMU columns
actionboolThe recording: an action feature
recorded_hand_poseboolThe recording: recorded hand keypoints
gripper_widthboolThe recording: a gripper-width column
episodesintegerThe dataset version: number of episodes

requires maps a fact to true, false, a string equal to the value, or a comparison such as ">=2" or "<600". If any condition is false, the step ends as not applicable: grey, never a failure. An unknown fact never satisfies a condition, so the step is not applicable rather than run on a guess. Your code can also decide at run time with ctx.not_applicable(code, message).

Resources

KeyDefaultMeaning
cpu4CPU cores.
memory8GiMemory, for example 8Gi or 16Gi.
disk10GiScratch space for ctx.tmp.
gpuNoneNone, or {"count": 1, "memoryGb": 16}.
timeout30mA duration such as 20m, or {"perInputMinute": …, "min": …, "max": …}.

Every step gets at least 4 CPU cores and 8Gi of memory, and at least 8 GB of GPU memory when it asks for a GPU; a smaller value runs with that floor. The resources must fit on one machine, and a GPU larger than any compute pool offers is refused with ALGORITHM_GPU_UNSATISFIABLE.

An algorithm that asks for a GPU runs on the CUDA SDK base automatically, with PyTorch and CUDA 13 preinstalled, so you never choose a base image. Its test runs also use a GPU and wait until one has room; a deployment without a GPU refuses them with ALGORITHM_SAMPLE_RUN_GPU_UNSUPPORTED.

GPU test runs haven't yet been proven end to end on a freshly installed deployment. If one misbehaves, send us the run id.

How code ends

How your code finishes tells the platform what happened, and each way ends the step differently. An image algorithm signals the same outcomes with its exit code.

PythonExit code (image)MeaningThe step ends
return0Done.succeeded
ctx.not_applicable(code, msg)85This data is not for me.not applicable
ctx.input_unusable(code, msg)87The data is broken.failed; the recording is quarantined
raise TransientError(msg)88Try again: network, GPU busy.retried, then failed
any other exception1A bug.failed; the traceback is in the log

Codes are capital letters, digits and _, 3 to 64 long. The step message reads <code>: <message>.

Versions and references

Workflows refer to an algorithm as embodiflow/<name>@<major> or team/<name>@<major>, and each run uses the highest saved version of that major. That way a fix reaches every workflow on its next run, while a breaking change waits until you switch to the new major.

A change to the ports, level, requires, the declared features, checks or labels, or the type of a parameter is a breaking change and needs a new major version; saving it as a minor version is refused with ALGORITHM_INTERFACE_CHANGED. A saved version never changes.

How run is called

run is called once per recording, once per episode at episode level, or once per dataset version for curate and export. Its arguments are bound by name, so take only the ones you need, in any order.

ArgumentGets
raw, recording, versionThe main input.
episodeEpisode level only: the episode being processed.
An extra input nameA Features object, or None when the input is optional and absent.
outThe writer of the category.
ctxThe context: params, facts, recording_id, run_id, step_id, tmp, log, progress(done, total, message), not_applicable and input_unusable.
stateWhat setup(ctx) returned.

Use setup(ctx) to load a model once. Today the platform calls it once per job; a later version may process many items in one job and still call setup only once, with no change to your code. That's why run must not keep per-item state in globals.

Next

  • SDK reference
  • Image algorithms
Previous

Use your algorithm in a workflow

Next

SDK reference