> For the complete documentation index, see [llms.txt](https://docs.pletor.ai/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.pletor.ai/documentation/api-reference/flows.md).

# Flows

Flows represent specific AI-powered capabilities — on-brand photo generation, UGC video generation, static ads generation, and more. Use these endpoints to discover available flows and inspect their required inputs and expected outputs. Flows are always described at their last saved version; Studio autosave drafts are never exposed here.

Discover flows and inspect their input requirements and output types.

## List Flows

> List available flows with filtering options.\
> \
> This endpoint returns a paginated list of flows that can generate various types of\
> content including images, videos, text, and other creative assets.\
> \
> Each flow is described at its last saved version. A flow that has never been\
> saved in Studio — autosave keeps it as a private draft — is still listed, but\
> with an empty \`inputs\` array and an \`estimated\_cost\` of \`0\`; it cannot be\
> fetched or run until someone saves it. Treat an empty \`inputs\` as "not saved\
> yet", not as "takes no input".\
> \
> \*\*Filtering Options:\*\*\
> \- \`tags\`: Only flows carrying every given tag slug, case-insensitive (can be\
> &#x20; provided multiple times; all must match)\
> \- \`visibility\`: Only flows with one of these visibilities (can be provided\
> &#x20; multiple times). Values are lowercase:\
> &#x20;   \- \`private\`: your organization's flows, visible only inside it\
> &#x20;   \- \`shared\`: your organization's flows shared by link\
> &#x20;   \- \`public\`: flows published to everyone, from any organization,\
> &#x20;     including Pletor's catalog\
> &#x20;  By default, only \`private\` and \`shared\` flows are returned.\
> \- \`search\`: Case- and accent-insensitive substring match on the flow name\
> \
> \*\*Pagination Parameters:\*\*\
> \- \`limit\`: Maximum number of items to return (default: 20, min: 1, max: 100)\
> \- \`cursor\`: \`next\_cursor\` from the previous page (optional)\
> \
> \*\*Response:\*\*\
> \- \`data\`: List of flow summaries with basic information including expected inputs\
> \- \`has\_more\`: Indicates if there are more results available\
> \- \`next\_cursor\`: Cursor for the next page of results; \`null\` on the last page\
> \
> \*\*Error Codes:\*\*\
> \- \`422\`: A parameter is out of range or not a valid value (e.g. an unknown\
> &#x20; \`visibility\`)\
> \
> \*\*Use Case:\*\* This is typically the first endpoint called to discover available flows\
> before getting detailed information or executing them.

```json
{"openapi":"3.1.0","info":{"title":"Pletor - Public API","version":"2.0.0"},"tags":[{"name":"flows","description":"Discover flows and inspect their input requirements and output types."}],"servers":[{"url":"/api/public"}],"security":[{"ApiKeyAuth":[]},{"BearerAuth":[]}],"components":{"securitySchemes":{"ApiKeyAuth":{"type":"apiKey","in":"header","name":"X-Api-Key","description":"API key for authentication"},"BearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"JWT","description":"Cognito JWT Bearer token"}},"schemas":{"FlowVisibility":{"type":"string","enum":["public","private"],"title":"FlowVisibility","description":"Visibility levels for workflows."},"CursorPaginatedResponse_FlowSummary_":{"properties":{"data":{"items":{"$ref":"#/components/schemas/FlowSummary"},"type":"array","title":"Data"},"has_more":{"type":"boolean","title":"Has More"},"next_cursor":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Next Cursor"}},"type":"object","required":["data","has_more"],"title":"CursorPaginatedResponse[FlowSummary]"},"FlowSummary":{"properties":{"id":{"type":"string","format":"uuid","title":"Id","description":"Unique flow identifier"},"name":{"type":"string","title":"Name","description":"Flow display name"},"description":{"type":"string","title":"Description","description":"Flow description and purpose; empty when none is set"},"tags":{"items":{"type":"string"},"type":"array","title":"Tags","description":"Tag slugs; filter on them with `tags` on `GET /flows/`"},"estimated_cost":{"type":"integer","title":"Estimated Cost","description":"Estimated credit cost per execution; `0` when not estimated or never saved"},"visibility":{"$ref":"#/components/schemas/FlowVisibility","description":"Visibility level: `private`, `shared`, or `public`"},"inputs":{"items":{"$ref":"#/components/schemas/FlowInput"},"type":"array","title":"Inputs","description":"All inputs for this flow; check the `required` flag on each to determine which are mandatory. Empty for a flow that was never saved"},"has_human_review":{"type":"boolean","title":"Has Human Review","description":"True when this flow includes a human review step that will pause execution until resolved via POST /runs/{run_id}/reviews/{review_id}. Poll GET /runs/{run_id} for `awaiting_human_review` while the run is in progress.","default":false}},"type":"object","required":["id","name","description","estimated_cost","visibility"],"title":"FlowSummary","description":"Lightweight flow summary for list views."},"FlowInput":{"properties":{"id":{"type":"string","title":"Id","description":"Node ID to use as `id` when providing this input"},"type":{"$ref":"#/components/schemas/NodeType","description":"Input type: `text_input` (text), or `image_input`, `video_input`, `audio_input` or `file_input` (uploaded asset IDs)"},"description":{"type":"string","title":"Description","description":"Generated from the input's label in Studio, as `Input for <label>`"},"required":{"type":"boolean","title":"Required","description":"Whether this input must be provided when creating a run; a missing required input answers `400 invalid_input`","default":true}},"type":"object","required":["id","type","description"],"title":"FlowInput","description":"An input a caller supplies when running a flow. Only user-input nodes are\nlisted; brand context is fixed in the flow and is never an input."},"NodeType":{"type":"string","enum":["text_input","image_input","file_input","video_input","audio_input","brand_system_input","input_font","llm","image_generation","video_generation","text_to_speech","screen_mockup","remove_background","upscale","upscale_video","video_background_removal","extract_video_frame","extend_video","reframe_video","image_generation_lora","change_aspect_ratio","crop_expand_image","color_grade_image","split_image_layers","merge_image_layers","meta_ads_extractor","image_edit","edit_text","relight_image","vectorize","image_erase","linkedin_ads_extractor","instagram_posts_extractor","linkedin_posts_extractor","human_review","match_brand_colors","tiktok_extractor","add_logo","video_subtitle","video_concat","video_add_sound","generic_fal","comment","group","composer","googledrive_find_file","googledrive_upload_file","prompt_concatenate","text_split","list_selector","video_edit","router","camera_angle","rename_asset","music_generation","generate_audio","merge_audio_video","trim_speed","extract_audio","remove_audio","isolate_sound","change_voice","translate_audio","translate_video","transcribe","run_task","run_agent"],"title":"NodeType"},"ApiErrorResponse":{"description":"Standard error response envelope. All API errors follow this format.","properties":{"error":{"$ref":"#/components/schemas/ApiErrorDetail","description":"Error details"}},"required":["error"],"title":"ApiErrorResponse","type":"object"},"ApiErrorDetail":{"description":"Structured details for an API error.","properties":{"code":{"$ref":"#/components/schemas/ApiErrorCode","description":"Machine-readable error code; branch on this, not on `message`"},"message":{"description":"Human-readable error description","title":"Message","type":"string"},"status":{"description":"HTTP status code of this response","title":"Status","type":"integer"},"details":{"additionalProperties":{"anyOf":[{"type":"string"},{"type":"integer"},{"type":"number"},{"type":"boolean"},{"items":{"type":"string"},"type":"array"},{"additionalProperties":{"type":"string"},"type":"object"},{"type":"null"}]},"description":"Additional context. Always holds `request_id` (the response's `X-Request-Id`); `validation_error` from request validation adds `errors`, a list of `location: message` strings, and `rate_limit_exceeded` adds `retry_after`, the seconds to wait.","title":"Details","type":"object"}},"required":["code","message","status","details"],"title":"ApiErrorDetail","type":"object"},"ApiErrorCode":{"description":"Machine-readable error code, with its usual HTTP status: `invalid_input`\n400, `authentication_required` 401, `forbidden` 403, `not_found` 404,\n`conflict` 409, `validation_error` 422, `rate_limit_exceeded` 429,\n`internal_error` 500, `run_failed` 502, `service_unavailable` 503, `timeout`\n504. A 4xx status without a code of its own is sent as `invalid_input`.","enum":["invalid_input","authentication_required","forbidden","not_found","conflict","validation_error","rate_limit_exceeded","internal_error","run_failed","service_unavailable","timeout"],"title":"ApiErrorCode","type":"string"}}},"paths":{"/v1/flows/":{"get":{"tags":["flows"],"summary":"List Flows","description":"List available flows with filtering options.\n\nThis endpoint returns a paginated list of flows that can generate various types of\ncontent including images, videos, text, and other creative assets.\n\nEach flow is described at its last saved version. A flow that has never been\nsaved in Studio — autosave keeps it as a private draft — is still listed, but\nwith an empty `inputs` array and an `estimated_cost` of `0`; it cannot be\nfetched or run until someone saves it. Treat an empty `inputs` as \"not saved\nyet\", not as \"takes no input\".\n\n**Filtering Options:**\n- `tags`: Only flows carrying every given tag slug, case-insensitive (can be\n  provided multiple times; all must match)\n- `visibility`: Only flows with one of these visibilities (can be provided\n  multiple times). Values are lowercase:\n    - `private`: your organization's flows, visible only inside it\n    - `shared`: your organization's flows shared by link\n    - `public`: flows published to everyone, from any organization,\n      including Pletor's catalog\n   By default, only `private` and `shared` flows are returned.\n- `search`: Case- and accent-insensitive substring match on the flow name\n\n**Pagination Parameters:**\n- `limit`: Maximum number of items to return (default: 20, min: 1, max: 100)\n- `cursor`: `next_cursor` from the previous page (optional)\n\n**Response:**\n- `data`: List of flow summaries with basic information including expected inputs\n- `has_more`: Indicates if there are more results available\n- `next_cursor`: Cursor for the next page of results; `null` on the last page\n\n**Error Codes:**\n- `422`: A parameter is out of range or not a valid value (e.g. an unknown\n  `visibility`)\n\n**Use Case:** This is typically the first endpoint called to discover available flows\nbefore getting detailed information or executing them.","operationId":"v1_list_flows_flows__get","parameters":[{"name":"tags","in":"query","required":false,"schema":{"anyOf":[{"type":"array","items":{"type":"string"}},{"type":"null"}],"description":"Only flows carrying every given tag slug (case-insensitive); repeat to require several","title":"Tags"},"description":"Only flows carrying every given tag slug (case-insensitive); repeat to require several"},{"name":"visibility","in":"query","required":false,"schema":{"anyOf":[{"type":"array","items":{"$ref":"#/components/schemas/FlowVisibility"}},{"type":"null"}],"description":"Only flows with one of these visibilities; repeat to allow several. Defaults to `private` and `shared`","title":"Visibility"},"description":"Only flows with one of these visibilities; repeat to allow several. Defaults to `private` and `shared`"},{"name":"search","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Case- and accent-insensitive substring of the flow name","title":"Search"},"description":"Case- and accent-insensitive substring of the flow name"},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":100,"minimum":1,"description":"Maximum number of items to return","default":20,"title":"Limit"},"description":"Maximum number of items to return"},{"name":"cursor","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Cursor for pagination (from next_cursor)","title":"Cursor"},"description":"Cursor for pagination (from next_cursor)"},{"name":"X-Organization-Id","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Active organization ID for multi-org support","title":"X-Organization-Id"},"description":"Active organization ID for multi-org support"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CursorPaginatedResponse_FlowSummary_"}}}},"422":{"description":"Validation error (`validation_error`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorResponse"}}}}}}}}}
```

## Get Flow

> Get detailed information about a specific flow.\
> \
> Everything below describes the flow's \*\*last saved version\*\*, not the draft you\
> are editing in Studio. Save the flow again to expose newer edits here and to\
> \`POST /runs\`.\
> \
> This endpoint retrieves comprehensive information about a flow, including:\
> \- Flow metadata (name, description, tags)\
> \- Input requirements with types\
> \- Output specifications and formats\
> \- Cost estimate, and whether the flow pauses for human review\
> \
> \*\*Input Information:\*\*\
> Each flow defines specific inputs it requires:\
> \- \`id\`: Node identifier used when executing the flow\
> \- \`type\`: Input type — \`text\_input\` takes text; \`image\_input\`, \`video\_input\`,\
> &#x20; \`audio\_input\` and \`file\_input\` take uploaded asset IDs\
> \- \`description\`: Generated from the input's Studio label\
> \- \`required\`: Whether \`POST /runs\` rejects a run that omits it\
> \
> Brand context is not an input: a flow's brand is fixed in the flow and is\
> never listed here or accepted by \`POST /runs\`.\
> \
> \*\*Output Information:\*\*\
> Each flow specifies what types of content it generates:\
> \- \`id\`: Node identifier for the output, matching \`id\` in run results\
> \- \`type\`: Output type (text, images, videos, audio, data)\
> \- \`description\`: Generated from the output type\
> \
> \*\*Cost and Review:\*\*\
> \- \`estimated\_cost\`: Credit cost estimation for running this flow\
> \- \`has\_human\_review\`: \`true\` when runs pause for a human review, resolved via\
> &#x20; \`POST /runs/{run\_id}/reviews/{review\_id}\`\
> \
> \*\*Use Case:\*\* Call this endpoint to understand what inputs a flow needs and what\
> outputs it will generate before creating a generation request.\
> \
> \*\*Error Codes:\*\*\
> \- \`404\`: Flow not found or not accessible\
> \- \`422\`: Flow has never been saved in Studio, so it has no version to\
> &#x20; describe, or \`flow\_id\` is not a UUID

```json
{"openapi":"3.1.0","info":{"title":"Pletor - Public API","version":"2.0.0"},"tags":[{"name":"flows","description":"Discover flows and inspect their input requirements and output types."}],"servers":[{"url":"/api/public"}],"security":[{"ApiKeyAuth":[]},{"BearerAuth":[]}],"components":{"securitySchemes":{"ApiKeyAuth":{"type":"apiKey","in":"header","name":"X-Api-Key","description":"API key for authentication"},"BearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"JWT","description":"Cognito JWT Bearer token"}},"schemas":{"Flow":{"properties":{"id":{"type":"string","format":"uuid","title":"Id","description":"Unique flow identifier"},"name":{"type":"string","title":"Name","description":"Flow display name"},"description":{"type":"string","title":"Description","description":"Flow description and purpose; empty when none is set"},"tags":{"items":{"type":"string"},"type":"array","title":"Tags","description":"Tag slugs; filter on them with `tags` on `GET /flows/`"},"inputs":{"items":{"$ref":"#/components/schemas/FlowInput"},"type":"array","title":"Inputs","description":"All inputs for this flow. Use these IDs when creating a run; check the `required` flag on each input to determine which are mandatory"},"outputs":{"items":{"$ref":"#/components/schemas/FlowOutput"},"type":"array","title":"Outputs","description":"Expected outputs. Match these IDs in run results, which can also hold other nodes. Output nodes with no public data type are not listed"},"estimated_cost":{"type":"integer","title":"Estimated Cost","description":"Estimated credit cost per execution; `0` when not estimated"},"has_human_review":{"type":"boolean","title":"Has Human Review","description":"True when this flow includes a human review step that will pause execution until resolved via POST /runs/{run_id}/reviews/{review_id}. Poll GET /runs/{run_id} for `awaiting_human_review` while the run is in progress.","default":false}},"type":"object","required":["id","name","description","estimated_cost"],"title":"Flow","description":"Complete representation of a flow with its inputs, outputs, and cost."},"FlowInput":{"properties":{"id":{"type":"string","title":"Id","description":"Node ID to use as `id` when providing this input"},"type":{"$ref":"#/components/schemas/NodeType","description":"Input type: `text_input` (text), or `image_input`, `video_input`, `audio_input` or `file_input` (uploaded asset IDs)"},"description":{"type":"string","title":"Description","description":"Generated from the input's label in Studio, as `Input for <label>`"},"required":{"type":"boolean","title":"Required","description":"Whether this input must be provided when creating a run; a missing required input answers `400 invalid_input`","default":true}},"type":"object","required":["id","type","description"],"title":"FlowInput","description":"An input a caller supplies when running a flow. Only user-input nodes are\nlisted; brand context is fixed in the flow and is never an input."},"NodeType":{"type":"string","enum":["text_input","image_input","file_input","video_input","audio_input","brand_system_input","input_font","llm","image_generation","video_generation","text_to_speech","screen_mockup","remove_background","upscale","upscale_video","video_background_removal","extract_video_frame","extend_video","reframe_video","image_generation_lora","change_aspect_ratio","crop_expand_image","color_grade_image","split_image_layers","merge_image_layers","meta_ads_extractor","image_edit","edit_text","relight_image","vectorize","image_erase","linkedin_ads_extractor","instagram_posts_extractor","linkedin_posts_extractor","human_review","match_brand_colors","tiktok_extractor","add_logo","video_subtitle","video_concat","video_add_sound","generic_fal","comment","group","composer","googledrive_find_file","googledrive_upload_file","prompt_concatenate","text_split","list_selector","video_edit","router","camera_angle","rename_asset","music_generation","generate_audio","merge_audio_video","trim_speed","extract_audio","remove_audio","isolate_sound","change_voice","translate_audio","translate_video","transcribe","run_task","run_agent"],"title":"NodeType"},"FlowOutput":{"properties":{"id":{"type":"string","title":"Id","description":"Node ID to match against `id` in run results"},"type":{"$ref":"#/components/schemas/DataType","description":"Output data type: text, images, videos, audio, or data"},"description":{"type":"string","title":"Description","description":"Generated from the data type, as `Generated <type>`"}},"type":"object","required":["id","type","description"],"title":"FlowOutput","description":"An output produced by a flow."},"DataType":{"type":"string","enum":["text","images","videos","files","audio","data"],"title":"DataType","description":"Kind of content an output, run result or review carries. In run results,\n`text` values are text, `images` / `videos` / `audio` values are asset IDs\nto download, and `data` values are structured JSON."},"ApiErrorResponse":{"description":"Standard error response envelope. All API errors follow this format.","properties":{"error":{"$ref":"#/components/schemas/ApiErrorDetail","description":"Error details"}},"required":["error"],"title":"ApiErrorResponse","type":"object"},"ApiErrorDetail":{"description":"Structured details for an API error.","properties":{"code":{"$ref":"#/components/schemas/ApiErrorCode","description":"Machine-readable error code; branch on this, not on `message`"},"message":{"description":"Human-readable error description","title":"Message","type":"string"},"status":{"description":"HTTP status code of this response","title":"Status","type":"integer"},"details":{"additionalProperties":{"anyOf":[{"type":"string"},{"type":"integer"},{"type":"number"},{"type":"boolean"},{"items":{"type":"string"},"type":"array"},{"additionalProperties":{"type":"string"},"type":"object"},{"type":"null"}]},"description":"Additional context. Always holds `request_id` (the response's `X-Request-Id`); `validation_error` from request validation adds `errors`, a list of `location: message` strings, and `rate_limit_exceeded` adds `retry_after`, the seconds to wait.","title":"Details","type":"object"}},"required":["code","message","status","details"],"title":"ApiErrorDetail","type":"object"},"ApiErrorCode":{"description":"Machine-readable error code, with its usual HTTP status: `invalid_input`\n400, `authentication_required` 401, `forbidden` 403, `not_found` 404,\n`conflict` 409, `validation_error` 422, `rate_limit_exceeded` 429,\n`internal_error` 500, `run_failed` 502, `service_unavailable` 503, `timeout`\n504. A 4xx status without a code of its own is sent as `invalid_input`.","enum":["invalid_input","authentication_required","forbidden","not_found","conflict","validation_error","rate_limit_exceeded","internal_error","run_failed","service_unavailable","timeout"],"title":"ApiErrorCode","type":"string"}}},"paths":{"/v1/flows/{flow_id}":{"get":{"tags":["flows"],"summary":"Get Flow","description":"Get detailed information about a specific flow.\n\nEverything below describes the flow's **last saved version**, not the draft you\nare editing in Studio. Save the flow again to expose newer edits here and to\n`POST /runs`.\n\nThis endpoint retrieves comprehensive information about a flow, including:\n- Flow metadata (name, description, tags)\n- Input requirements with types\n- Output specifications and formats\n- Cost estimate, and whether the flow pauses for human review\n\n**Input Information:**\nEach flow defines specific inputs it requires:\n- `id`: Node identifier used when executing the flow\n- `type`: Input type — `text_input` takes text; `image_input`, `video_input`,\n  `audio_input` and `file_input` take uploaded asset IDs\n- `description`: Generated from the input's Studio label\n- `required`: Whether `POST /runs` rejects a run that omits it\n\nBrand context is not an input: a flow's brand is fixed in the flow and is\nnever listed here or accepted by `POST /runs`.\n\n**Output Information:**\nEach flow specifies what types of content it generates:\n- `id`: Node identifier for the output, matching `id` in run results\n- `type`: Output type (text, images, videos, audio, data)\n- `description`: Generated from the output type\n\n**Cost and Review:**\n- `estimated_cost`: Credit cost estimation for running this flow\n- `has_human_review`: `true` when runs pause for a human review, resolved via\n  `POST /runs/{run_id}/reviews/{review_id}`\n\n**Use Case:** Call this endpoint to understand what inputs a flow needs and what\noutputs it will generate before creating a generation request.\n\n**Error Codes:**\n- `404`: Flow not found or not accessible\n- `422`: Flow has never been saved in Studio, so it has no version to\n  describe, or `flow_id` is not a UUID","operationId":"v1_get_flow_flows__flow_id__get","parameters":[{"name":"flow_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Flow Id"}},{"name":"X-Organization-Id","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Active organization ID for multi-org support","title":"X-Organization-Id"},"description":"Active organization ID for multi-org support"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Flow"}}}},"422":{"description":"Validation error (`validation_error`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorResponse"}}}}}}}}}
```
