Key in the keychain
Stored in macOS Keychain (0600 file elsewhere). Env vars need an explicit opt-in. Every byte of output goes through a redactor.
Open source · MIT · 0 runtime dependencies
A command-line tool that lets AI agents create images and video on KIE.ai — without ever handing them the API key, and with a hard ceiling on what a single run can spend.
$ npm i -g @uxdata-co/kie
╭─●─╮ ╱ ╲ ╱ ╱╲ ╲ kie v0.2.0 ╱ ╱ ╲ ╲ ╲ KIE.ai media generation for agents & humans ╱ ╱────╲ ╲ ╲ images · video · zero dependencies · spend-guarded ╱ ╱ ╲ ╲ ●───╯ ╱ ╲ ╲ ╰───● $ kie credits ╭─ ▲ kie credits ──────────────────────────────────╮ │ balance 980 credits ≈ US$4.90 │ │ today 16 / 200 ████████████████████████ 8% │ │ remaining today 184 credits │ ╰──────────────────────────────────────────────────────╯ $ kie image nano-banana-2 --prompt "isometric coffee shop" --aspect 16:9 ⠹ nano-banana-2 generating 40% task_c0ffee12 14s ╭─ ▲ kie generation complete ────────────────────────╮ │ state success │ │ credits 8 │ │ files kie-media/nano-banana-2-c0ffee12.png │ ╰──────────────────────────────────────────────────────╯
Why another CLI
Media APIs are the most expensive credentials to leak. Most integrations read the key from an env var, pull in hundreds of packages and ship a default webhook. kie does none of that.
Stored in macOS Keychain (0600 file elsewhere). Env vars need an explicit opt-in. Every byte of output goes through a redactor.
Talks only to api.kie.ai and KIE's upload host. Never sends a callBackUrl — results are polled, nothing about your generations is pushed anywhere.
Per-task cap, a daily budget computed from the real credits KIE reports, and a balance check. Blocked means nothing left your machine.
JSON on stdout, messages on stderr, exit codes you can branch on. Pretty tables when a human runs it in a terminal.
Node ≥ 20 built-ins only. The code that touches your key is ~700 lines you can read before trusting it.
KIE result URLs expire in 24 hours. kie writes files to disk and hands back paths, never links.
Install
Node ≥ 20. Published from GitHub Actions with provenance — npm audit signatures verifies the tarball came from the repo.
npm i -g @uxdata-co/kie
kie version
At kie.ai/api-key, make a key just for agents and set hourly/daily caps plus an IP whitelist. KIE enforces those even if this CLI is bypassed.
# https://kie.ai/api-key → new key → caps + IP whitelist
Input is hidden. The key goes to the Keychain and never appears in output again.
kie key set
kie key check
Usage
kie image nano-banana-2 \
--prompt "isometric coffee shop, warm light" \
--aspect 16:9 --resolution 2K --out ./assets
kie video kling-3.0 \
--prompt "drone shot over a fjord at dawn" \
--duration 5 --sound --max-credits 80
kie upload ./sketch.png # → temporary URL
kie image nano-banana-2 \
--prompt "same scene at night" \
--ref https://…/sketch.png
kie run some-vendor/some-model \
--input '{"prompt":"…"}' --max-credits 30
{
"taskId": "task_c0ffee12",
"model": "nano-banana-2",
"state": "success",
"creditsConsumed": 8,
"files": ["kie-media/nano-banana-2-c0ffee12.png"]
}
Tutorials
This is the whole point: your coding agent makes the media, you keep the key. One install, one skill, then you just ask.
npm i -g @uxdata-co/kie
kie key set
kie skill install # Claude Code + Codex
kie skill install --agent codex # just one
Prefer the skills CLI? npx skills add julio-daza/kie-cli does the same for any supported agent.
Start a new session — skills are discovered at startup. CLI, desktop app and IDE extension all read ~/.claude/skills/.
Ask in plain language. The description triggers the skill; /kie-media invokes it explicitly.
Claude checks the budget, generates, downloads, and answers with the file path and credits spent.
$ kie credits --json$ kie image nano-banana-2 --prompt "isometric coffee shop, warm light" --aspect 16:9 --out ./assets --name hero-coffee --json
Start a new session — CLI, IDE extension and desktop app all read ~/.agents/skills/. /skills lists what is installed.
Ask naturally, or call it with $kie-media. For video, say the cap out loud.
Codex runs the CLI with --json and reports the file path; a blocked request (exit 3) comes back with the reason.
$ kie upload ./assets/hero-coffee.png --json$ kie video kling-3.0 --prompt "barista slides a cup across the counter, soft dolly-in" --image <url> --duration 5 --sound --max-credits 80 --json
Daily ceiling for everything the agent does: kie config set dailyBudget 300
Spend guard
KIE doesn't publish per-model prices in its API docs, so kie doesn't guess. It layers three independent checks and refuses with exit code 3 if any fails.
| 0 | success |
| 1 | task failed on KIE's side |
| 2 | usage error |
| 3 | blocked by the spend guard |
| 4 | timed out — task still running, resume with kie wait |
| 5 | API / auth error |
Models with a verified price are compared against maxCreditsPerTask. Everything else requires an explicit --max-credits — the agent has to say out loud how much it accepts to spend.
A local ledger records every task; when it completes, the real creditsConsumed is written back. Pending tasks count at their cap, so a burst can't overshoot.
If the estimate exceeds what's left on the account, the request never leaves.
$ kie video kling-3.0 --prompt "drone shot over a fjord" ✖ Spend guard blocked the request: This model has no known credit estimate. Re-run with --max-credits <n> to state the most you accept to spend on this task. Today: 16 credits used, 184 remaining. Balance: 980. $ echo $? 3
Documentation
| kie key set|check|delete | Store the API key (Keychain / 0600 file), verify it, remove it. |
| kie credits | Balance plus today's spend against the daily budget. |
| kie models [--kind image|video] | Curated catalog with the flags each model supports. |
| kie image <model> --prompt … [opts] | Generate an image, wait, download. |
| kie video <model> --prompt … [opts] | Generate a video, wait, download. |
| kie run <model-id> --input '{…}' --max-credits N | Escape hatch for any KIE Market model. |
| kie status <taskId> | One poll, no download. |
| kie wait <taskId> [--out dir] | Poll until done, download, settle the ledger. |
| kie upload <file> | Local file → temporary URL for --ref / --image (KIE deletes it after ~3 days). |
| kie ledger [--limit 20] | Local spend log with real creditsConsumed. |
| kie config set <key> <value> | dailyBudget · maxCreditsPerTask · outDir · pollSeconds · waitTimeoutSeconds |
| kie skill install [--agent claude|codex|all] | Install the kie-media agent skill for Claude Code / Codex (--project for the current repo). |
| --prompt <text> | The prompt. |
| --ref <url> | Reference image, repeatable (edit / style / multimodal reference). |
| --image <url> / --end-image <url> | First and last frame for video. |
| --aspect, --resolution, --duration | 16:9 · 1K|2K|4K|720p · seconds |
| --sound, --fast, --format | Native audio · cheaper variant · png|jpg |
| --set key=value | Raw model field, repeatable. callBackUrl is rejected. |
| --max-credits <n> | Accept spending up to n credits on this task. |
| --dry-run | Print the exact request, send nothing. |
| --out <dir>, --name <base>, --no-wait | Where files go · base filename · submit and return. |
| --json, --pretty, --no-color, --quiet | Output control. JSON is automatic when piped. |
| nano-banana-2 | image | Google Nano Banana 2 — generate + edit with up to 14 refs. Est. 1K=8 · 2K=12 · 4K=18 credits. |
| seedream-v4 | image | ByteDance Seedream V4 — text-to-image, switches to edit with --ref. |
| kling-3.0 | video | Kling 3.0 — 3–15 s, native audio, --set mode=pro. |
| seedance-2.5 | video | ByteDance Seedance 2.5 — frames or multimodal refs, 4–30 s. |
| minimax-h3 | video | MiniMax H3 — sub-model chosen from your flags (text / image / reference). |
| veo3 | video | Google Veo 3 — own endpoint, --fast for veo3_fast. |
Agent skill
The package ships an agent skill (Agent Skills spec) for Claude Code and Codex. It tells the agent when to generate, which model to pick, to check the budget first, to always pass --max-credits on video, and to return file paths — never URLs.
kie skill install # ~/.claude/skills + ~/.agents/skills
npx skills add julio-daza/kie-cli # alternative
FAQ
No. It's an independent, community project. KIE and its logo are trademarks of their owner, used only to identify the service.
Yes. Without a Keychain the key is stored in ~/.config/kie/key with 0600 permissions. Everything else is identical.
Every release is published by GitHub Actions from a git tag, with npm provenance: the tarball is cryptographically linked to the commit and workflow that produced it. Zero runtime dependencies, so what you audit is what runs.
kie run <model-id> --input '{…}' --max-credits N sends any KIE Market model. Check the schema on docs.kie.ai first, or use --dry-run.
Of course. In a terminal it renders tables, panels and a live spinner; pipe it and you get JSON.
MIT licensed. Read the source before you trust it with a key — that's the point.
View on GitHub →