Build and execute skills.video image generation REST requests from OpenAPI specs.
# Install Skill (downloads SKILL.md to .claude/skills/) clawhub install skills-video/ai-image # Then just tell Claude: "use AI Image to help me..."
# Same install command — works with all SKILL.md-compatible AI coding tools clawhub install skills-video/ai-image
This Skill is compatible with the OpenClaw standard. After installation, a SKILL.md file is auto-generated, usable by any OpenClaw-compatible AI Agent (Claude Code, Cursor, Windsurf, etc.).
skills.video.
Prefer deterministic extraction from openapi.json instead of guessing fields.https://skills.video/dashboard/developerSKILLS_VIDEO_API_KEY before using the skill.ai-imageSKILLS_VIDEO_API_KEY{
"skills": {
"entries": {
"ai-image": {
"enabled": true,
"env": {
"SKILLS_VIDEO_API_KEY": "your_api_key_here"
}
}
}
}
}
export SKILLS_VIDEO_API_KEY="your_api_key_here"SKILLS_VIDEO_API_KEYPOST /generation/sse/... as default and keep the stream open.GET /generation/{id} to terminal status.COMPLETED/SUCCEEDED/FAILED/CANCELED), never IN_PROGRESS.python scripts/ensure_api_key.py
ok is false, tell the user to:Prerequisitesexport SKILLS_VIDEO_API_KEY="<YOUR_API_KEY>"
/v1/openapi.json under a model namespace).openapi.json.references/open-platform-api.md for base URL, auth, and async lifecycle.docs.json exists, derive image endpoints from the Images navigation group.
Use default_endpoints from the script output as the primary list (SSE first).python scripts/inspect_openapi.py \
--openapi /abs/path/to/openapi.json \
--docs /abs/path/to/docs.json \
--list-endpoints
docs.json is unavailable, pass a known endpoint directly (for example /generation/sse/google/nano-banana-pro).
Use references/image-model-endpoints.md as a snapshot list.python scripts/inspect_openapi.py \
--openapi /abs/path/to/openapi.json \
--endpoint /generation/sse/google/nano-banana-pro \
--include-template
request_template as the starting point.
Do not add fields not defined by the endpoint schema.
Use default_create_endpoint from output unless an explicit override is required.python scripts/create_and_wait.py \
--sse-endpoint /generation/sse/google/nano-banana-pro \
--payload '{"prompt":"Minimal product photo of a matte black coffee grinder on white background"}' \
--poll-timeout 900 \
--poll-interval 3
IN_QUEUE or IN_PROGRESS.
Return only after terminal result.GET /generation/{id} (or model-spec equivalent path if the OpenAPI uses /v1/...).curl -X GET "https://open.skills.video/api/v1/generation/<GENERATION_ID>" \
-H "Authorization: Bearer $SKILLS_VIDEO_API_KEY"
COMPLETEDFAILEDCANCELEDpython scripts/wait_generation.py \
--generation-id <GENERATION_ID> \
--timeout 900 \
--interval 3
event=terminal.400: request format issue401: missing/invalid API key402: possible payment/credits issue in runtime404: endpoint or generation id not found422: schema validation failedpython scripts/handle_runtime_error.py \
--status <HTTP_STATUS> \
--body '<RAW_ERROR_BODY_JSON_OR_TEXT>'
insufficient_credits, tell the user to recharge:https://skills.video/dashboard and go to Billing/Creditscurl -X GET "https://open.skills.video/api/v1/credits" \
-H "Authorization: Bearer $SKILLS_VIDEO_API_KEY"
5xx).
Use bounded exponential backoff (for example 1s, 2s, 4s, max 16s, then fail).
Do not retry unchanged payloads after 4xx validation errors.scripts/ensure_api_key.py: validate SKILLS_VIDEO_API_KEY and show first-run setup guidancescripts/handle_runtime_error.py: classify runtime errors and provide recharge guidance for insufficient creditsscripts/inspect_openapi.py: extract SSE/polling endpoint pair, contract, and payload templatescripts/create_and_wait.py: create via SSE and auto-fallback to polling when stream does not reach terminal statusscripts/wait_generation.py: poll generation status until terminal completion and return final responsereferences/open-platform-api.md: SSE-first lifecycle, fallback polling, retry baselinereferences/image-model-endpoints.md: current image endpoint snapshot from docs.jsonReal cold-start runs of this skill on Claude Code and Codex.
Input: With NO API key, deterministically extract an image-generation SSE endpoint + request schema from skills.video’s 194-path OpenAPI spec, build a minimal valid payload (required fields only), and execute to confirm the request is well-formed — expecting HTTP 401 (auth-gated), not 400 (malformed) or 404 (wrong endpoint).
Resolved the requestBody $ref → a schema whose only required field is `prompt` (additionalProperties:false), so the minimal payload is just {prompt}. Chose /generation/sse/google/nano-banana; POST returned 401 "API key required" — well-formed, auth-gated. (Same session also built the video request.)
claude-opus-4-8
Same deterministic extraction over the 1.8 MB spec (more granular jq probing); chose /generation/sse/bytedance/seedream-4.0, confirmed only `prompt` required + additionalProperties:false, built {prompt}, POST 401. 12 shell steps.
View transcriptcodex-cli 0.140
Output: Both built schema-valid minimal payloads {"prompt":"a serene mountain lake at sunset"} for a real image-gen SSE endpoint; both POSTs returned 401 "API key required" — correct, auth-gated requests (not 400/404). Claude→google/nano-banana, Codex→bytedance/seedream-4.0.
Verdict: Faithful no-key test of the skill’s actual job (turn the OpenAPI spec into a correct generation request). Both passed — valid schema-derived payloads reaching the 401 auth boundary. NOTE: no image is generated here; real output requires the user’s SKILLS_VIDEO_API_KEY (paid skills.video API) — only the final execute step is key-gated. Efficiency favors Claude (5 vs 12 actions).
Environment: macOS · public OpenAPI spec (open.skills.video/api/v1/openapi.json, 194 paths) · symmetric cold start. No-key run: this skill is an API-request builder ("deterministic extraction from openapi.json"), so we test its actual competency — constructing a valid generation request from the spec. Execution is auth-gated (SKILLS_VIDEO_API_KEY not set → expected 401). Image + video requests were built in one combined session per agent.