Install
openclaw skills install comfyui-runninghubExecute RunningHub ComfyUI workflows via API. Use when you need to run ComfyUI workflows on RunningHub cloud platform, submit tasks, query status, and retrie...
openclaw skills install comfyui-runninghubThis skill provides tools to execute ComfyUI workflows on the RunningHub cloud platform via API.
https://www.runninghub.ai/#/workflow/WORKFLOW_ID1987728214757978114cd /root/.openclaw/workspace/skills/runninghub-comfyui
python3 scripts/runninghub_client.py --save-key YOUR_API_KEY
The API key will be saved to config.json and automatically loaded for future runs.
export RUNNINGHUB_API_KEY=YOUR_API_KEY
python3 scripts/runninghub_client.py --api-key YOUR_API_KEY ...
For workflows using default configuration:
cd /root/.openclaw/workspace/skills/runninghub-comfyui
python3 scripts/runninghub_client.py \
--workflow-id 1987728214757978114 \
--action submit
Upload an image and run the workflow with it:
python3 scripts/runninghub_client.py \
--workflow-id 1987728214757978114 \
--action run-with-image \
--image /path/to/your/image.png \
--node-id 107 \
--field-name image
Parameters:
--image: Path to the local image file--node-id: The node ID for image input (default: 107)--field-name: The field name for image input (default: image)python3 scripts/runninghub_client.py \
--task-id TASK_ID \
--action query
python3 scripts/runninghub_client.py \
--task-id TASK_ID \
--action wait \
--poll-interval 5 \
--max-attempts 60
from runninghub_client import RunningHubClient, load_config, get_api_key
# Get API key from config
api_key = get_api_key()
# Initialize client
client = RunningHubClient(api_key)
# Upload image and get URL
image_url = client.upload_image("/path/to/image.png")
print(f"Image URL: {image_url}")
# Submit workflow with custom image
result = client.submit_workflow_with_image(
workflow_id="1987728214757978114",
node_id="107",
field_name="image",
image_url=image_url
)
task_id = result["taskId"]
# Wait for completion
final_result = client.wait_for_completion(task_id)
# Get output URLs
if final_result.get("status") == "SUCCESS":
for item in final_result.get("results", []):
print(f"Output: {item.get('url')}")
__init__(api_key: str)Initialize the client with your API KEY.
upload_image(image_path: str) -> Optional[str]Upload an image file to RunningHub and get the URL.
Returns:
None on failuresubmit_workflow(workflow_id: str, node_info_list: Optional[list]) -> DictSubmit a workflow task for execution.
Parameters:
workflow_id: The workflow ID from RunningHubnode_info_list: Node configuration list (optional)Important: Use fieldValue (not value) in node_info_list:
node_info_list = [
{
"nodeId": "107",
"fieldName": "image",
"fieldValue": "https://..." # ✅ Use fieldValue, not value
}
]
Returns:
{
"taskId": "TASK_ID",
"status": "RUNNING",
"clientId": "CLIENT_ID"
}
submit_workflow_with_image(workflow_id: str, node_id: str, field_name: str, image_url: str) -> DictSubmit a workflow with an image input (convenience method).
Example:
result = client.submit_workflow_with_image(
"1987728214757978114", # workflow_id
"107", # node_id
"image", # field_name
"https://..." # image_url
)
query_task(task_id: str) -> DictQuery the status of a submitted task.
Returns:
{
"status": "RUNNING|SUCCESS|FAILED",
"results": [
{"url": "https://...", "filename": "..."}
]
}
wait_for_completion(task_id: str, poll_interval: int, max_attempts: int) -> DictWait for a task to complete by polling status.
Endpoint: POST /openapi/v2/media/upload/binary
Headers:
Authorization: Bearer <api_key>Body:
Response:
{
"code": 0,
"msg": "success",
"data": {
"type": "image",
"download_url": "https://...",
"fileName": "openapi/...",
"size": "3490"
}
}
Endpoint: POST /openapi/v2/run/workflow/{workflow_id}
Headers:
Authorization: Bearer <api_key>Content-Type: application/jsonRequest Body:
{
"apiKey": "your-api-key",
"workflowId": "1987728214757978114",
"addMetadata": true,
"nodeInfoList": [
{
"nodeId": "107",
"fieldName": "image",
"fieldValue": "https://..." // ✅ Use fieldValue, not value
}
],
"instanceType": "default",
"usePersonalQueue": "false"
}
Important: Use fieldValue not value for node input values!
Use fieldValue not value: When passing node input values via API, always use fieldValue:
{"nodeId": "107", "fieldName": "image", "fieldValue": "..."} // ✅ Correct
{"nodeId": "107", "fieldName": "image", "value": "..."} // ❌ Wrong
Rate Limiting: Basic members have concurrency limits (usually 1 task at a time)
Error 421: "API queue limit reached" - Wait for previous tasks to complete
Authentication: Uses Authorization: Bearer <api_key> header
API Endpoints:
POST /openapi/v2/run/workflow/{workflow_id}POST /openapi/v2/queryPOST /openapi/v2/media/upload/binaryfieldValue not valuegetJsonApiFormat endpoint to check available nodes