PVL Sam3 Segmentation (fal.ai)
Name an object, get a SAM-3 mask — the heavyweight, hosted
- image
- preview
- mask
- scores_json
- boxes_json
SAM is the segmentation foundation model that made "click on it, get a mask" feel like magic, and SAM-3 is the current generation of that idea. This node puts fal.ai's hosted fal-ai/sam-3/image endpoint in your graph: you give it an image and a prompt like wheel, and it returns the mask of every wheel, not a hand-drawn cutout.
Where this earns its keep is targeted object selection. Background removal (foreground vs. everything else) is a different job - SAM is for "find that specific thing I can describe." If your workflow is "segment the car, then the wheel, then the headlight, and inpaint each," that's a chain of SAM calls, and this node turns each one into a single node in the graph.
How it works
The image goes to fal as a base64 data URI - no storage upload, which keeps things snappy - and the node submits all batch items in parallel, then polls for results. What you get back is a mask (or a stack of masks), plus JSON with the model's confidence scores and bounding boxes if you ask for them.
The advanced inputs are JSON strings, and they're where the power lives:
point_prompts_json- click-style hints:[{"x": 120, "y": 220, "label": 1, "object_id": 0}].label1 is foreground, 0 is background. This is your "click on it" in API form.box_prompts_json- an explicit region:[{"x_min": 10, "y_min": 20, "x_max": 400, "y_max": 500, "object_id": 0}].
If you've ever run local SAM, this is familiar territory - the prompts are the same, they're just JSON now.
The inputs that matter
prompt- the object name. Default iswheel, which is a giveaway that this node was tested on a car. It's optional in spirit; if the prompt is empty, point/box prompts take over.apply_mask- true by default. When on, you get the mask applied to the image in the preview output; turn it off if you only want the raw mask.return_multiple_masks+max_masks- SAM can return several candidate masks per object. The MASK output only ever carries the first one; the rest show up as metadata inscores_json/boxes_json.include_scores/include_boxes- flip these on when you want the JSON outputs populated.sync_mode- false by default; leave it.
Outputs: preview (IMAGE), mask (MASK), scores_json (STRING), boxes_json (STRING).
Installing it
Part of the pvlprk "ComfyUI Assistant Node" pack:
cd ComfyUI/custom_nodes
git clone https://github.com/pvlprk/comfyui-pvl-api-nodes
Restart, then set FAL_KEY in the environment. No models download - SAM-3 runs on fal's hardware, which is the whole point if you don't have the VRAM for a local SAM-3.
Common issues
The first gotcha is the multiple-mask thing: the node explicitly returns only the first mask as a MASK output, so if your object has several plausible segmentations and the "right" one is #2, you need the JSON side of this node, not the mask port. Second, a prompt of wheel matches all wheels - "return multiple" exists for a reason. Third, remember this is targeted masking, not background removal; don't reach for it to cut a subject out of a studio photo, that's the remove-background node in the same pack. And the usual: FAL_KEY unset throws, images leave your machine, and per-request billing means a big batch of point prompts isn't free.
Inputs (11)
| Name | Type | Default | Description |
|---|---|---|---|
| image | IMAGE | — | |
| prompt | STRING | wheel | — |
| apply_mask | BOOLEAN | true | — |
| output_format | COMBO | png | 3 options: png, jpeg, webp |
| return_multiple_masks | BOOLEAN | false | — |
| max_masks | INT | 31–32 | — |
| include_scores | BOOLEAN | false | — |
| include_boxes | BOOLEAN | false | — |
| sync_mode | BOOLEAN | false | — |
| point_prompts_jsonopt | STRING | [] | — |
| box_prompts_jsonopt | STRING | [] | — |
Outputs (4)
| Name | Type | Description |
|---|---|---|
| preview | IMAGE | — |
| mask | MASK | — |
| scores_json | STRING | — |
| boxes_json | STRING | — |