Install
openclaw skills install openclaw-selfieGenerate identity-consistent selfies, group photos, and other SFW images for OpenClaw characters via the tuqu.ai API. Use when creating character portraits, selfies (自拍), photo shoots (写真), group shots (合影), or any image generation request where the character's appearance must stay consistent across images. Covers prompt enhancement, preset discovery, character management, billing, and recharge flows. Also handles 照片, 发张图, 角色出镜, 风景, and edit-only images.
openclaw skills install openclaw-selfieGenerate photos where your OpenClaw character looks the same every time — selfies, group shots, portraits, stylized scenes, and more — all through tuqu.ai's image generation API. The skill handles character identity preservation, prompt enhancement, preset application, balance management, and billing.
clawhub install openclaw-selfie
Or with the native OpenClaw command:
openclaw skills install openclaw-selfie
python3 in PATH).--service-key.After installation, verify the skill is working:
# Check that the helper script runs
python3 scripts/tuqu_request.py GET /api/catalog --query type=all
# Check available models and pricing
python3 scripts/tuqu_request.py GET /api/pricing-config
If both commands return JSON, the skill is ready. Authenticated calls (generation, balance, etc.)
also require --service-key <your-role-service-key>.
Only set these when you need to point at a non-default host:
TUQU_BASE_URL — defaults to https://photo.tuqu.aiTUQU_BILLING_BASE_URL — defaults to https://billing.tuqu.ai/dream-weaverAll API calls go through scripts/tuqu_request.py. The helper auto-selects the correct host and
auth mode for each endpoint, keeps credentials explicit via --service-key, and prints formatted
JSON for direct inspection.
Detailed API semantics are in TUQU_API.md. Exact request/response fields are in references/endpoints.md and task sequences in references/workflows.md.
Authenticated calls must pass --service-key <role-service-key> explicitly on every request. Do not
rely on a shared credential environment variable — different OpenClaw roles can carry different keys.
List or query data:
python3 scripts/tuqu_request.py GET /api/catalog --query type=all
python3 scripts/tuqu_request.py GET /api/model-costs
python3 scripts/tuqu_request.py GET /api/pricing-config
Send a small JSON body inline:
python3 scripts/tuqu_request.py POST /api/enhance-prompt \
--json '{"category":"portrait","prompt":"soft editorial portrait with window light"}'
Send a larger payload from disk:
python3 scripts/tuqu_request.py POST /api/v2/generate-image \
--service-key <role-service-key> \
--body-file payloads/generate-image.json
Override helper defaults only with a documented reason:
python3 scripts/tuqu_request.py POST /api/custom-path \
--base-url https://photo.tuqu.ai \
--auth-mode user-key \
--service-key <role-service-key> \
--json '{"prompt":"example"}'
Before picking an endpoint, classify the user request into one of these buckets:
自拍, 照片, 写真, 发张图, or similar wording that implies the current role should be in frameIf the request is ambiguous, decide whether the current role needs to appear in the final image.
自拍 as current-role-on-camera by default.自拍 means the current role appears in the image. It does not mean a phone must be visible.Use identity-preserving routing when the current role must appear:
POST /api/v2/generate-for-characterPOST /api/v2/generate-imageKeep all supported calls on scripts/tuqu_request.py.
When the current role must appear in the frame, enforce this order:
/api/characters./api/billing/balance./api/v2/generate-for-character.Helper sequence:
python3 scripts/tuqu_request.py GET /api/characters --service-key <role-service-key>
python3 scripts/tuqu_request.py POST /api/characters \
--service-key <role-service-key> \
--body-file payloads/create-character.json
python3 scripts/tuqu_request.py POST /api/billing/balance --service-key <role-service-key>
python3 scripts/tuqu_request.py POST /api/v2/generate-for-character \
--service-key <role-service-key> \
--body-file payloads/generate-for-character.json
Use the create-character step only when the current role does not already have a usable Tuqu character.
自拍 or 发张图, assume the goal is a natural current-role portrait rather
than a literal handheld-phone shot.python3 scripts/tuqu_request.py GET /api/catalog --query type=all
python3 scripts/tuqu_request.py GET /api/model-costs
python3 scripts/tuqu_request.py GET /api/pricing-config
Use /api/pricing-config before accepting a user-supplied model name. Match the requested model
to a real models[].id, then use that modelId in later generation payloads.
python3 scripts/tuqu_request.py POST /api/enhance-prompt \
--json '{"category":"portrait","prompt":"soft editorial portrait with window light"}'
python3 scripts/tuqu_request.py POST /api/v2/generate-image \
--service-key <role-service-key> \
--body-file payloads/generate-image.json
Example payloads/generate-image.json:
{
"prompt": "cinematic portrait in warm sunset light",
"referenceImageUrls": ["https://example.com/reference.jpg"],
"resolution": "2K",
"ratio": "Original",
"modelId": "seedream45"
}
python3 scripts/tuqu_request.py GET /api/catalog --query type=all
python3 scripts/tuqu_request.py POST /api/v2/apply-preset \
--service-key <role-service-key> \
--body-file payloads/apply-preset.json
python3 scripts/tuqu_request.py GET /api/characters --service-key <role-service-key>
python3 scripts/tuqu_request.py POST /api/characters \
--service-key <role-service-key> \
--body-file payloads/create-character.json
python3 scripts/tuqu_request.py PUT /api/characters/<character-id> \
--service-key <role-service-key> \
--body-file payloads/update-character.json
python3 scripts/tuqu_request.py DELETE /api/characters/<character-id> \
--service-key <role-service-key>
python3 scripts/tuqu_request.py GET /api/characters --service-key <role-service-key>
python3 scripts/tuqu_request.py POST /api/billing/balance --service-key <role-service-key>
python3 scripts/tuqu_request.py POST /api/v2/generate-for-character \
--service-key <role-service-key> \
--body-file payloads/generate-for-character.json
Optionally refine the scene prompt first with /api/enhance-prompt. When the request is a selfie
or other current-role portrait, make sure the character check and balance check happen before the
generation call.
python3 scripts/tuqu_request.py GET /api/history --service-key <role-service-key>
python3 scripts/tuqu_request.py POST /api/history \
--service-key <role-service-key> \
--body-file payloads/history-item.json
python3 scripts/tuqu_request.py DELETE /api/history/<history-id> --service-key <role-service-key>
python3 scripts/tuqu_request.py POST /api/billing/balance --service-key <role-service-key>
python3 scripts/tuqu_request.py GET /api/v1/recharge/plans --service-key <role-service-key>
python3 scripts/tuqu_request.py POST /api/v1/recharge/wechat \
--service-key <role-service-key> \
--json '{"planId":"698b7fead4c733c85f2a9c74"}'
python3 scripts/tuqu_request.py POST /api/v1/recharge/stripe \
--service-key <role-service-key> \
--json '{"planId":"698b7fead4c733c85f2a9c74","successUrl":"https://your-app.com/payment/success","cancelUrl":"https://your-app.com/payment/cancel"}'
scripts/tuqu_request.py instead of ad-hoc curl for supported endpoints./api/v2/generate-for-character./api/v2/generate-image.--service-key on every authenticated helper call.--body-file for large JSON payloads, especially generation and preset payloads./api/catalog as the source of truth for presetId, preset type, and preset variables./api/pricing-config to resolve user-supplied model names before setting modelId.自拍 as front-camera composition with the current role visible and the phone not
visible unless explicitly requested.