Install any skill in seconds. Free to start, no credit card required.
Get Started Free →Configure Kling AI for teams with per-project API keys, usage quotas, and role-based access. Trigger with phrases like 'klingai team', 'kling ai organization', 'klingai multi-user', 'shared klingai access'.
.claude/skills/jeremylongshore-klingai-team-setup/SKILL.md| Test case | Without → With | Effect | Δ tokens | Δ turns |
|---|---|---|---|---|
| case-03 | ✗→✓ | ▲ Improved | 46% | 0% |
| case-04 | ✗→✓ | ▲ Improved | 143% | 0% |
| case-06 | ✗→✓ | ▲ Improved | 45% | 0% |
| case-12 | ✗→✓ | ▲ Improved | 11% | 0% |
| case-07 | ✗→✓ | ▲ Improved | 49% | 0% |
Manage team access to the Kling AI API using separate API keys, environment-based routing, usage quotas per team member, and centralized credential management.
Create separate API key pairs in the Kling AI developer console for each environment:
| Environment | Key Naming Convention | Purpose | |------------|----------------------|---------| | Development | dev-<project> | Local testing, free tier | | Staging | staging-<project> | Integration testing | | Production | prod-<project> | Live traffic |
bash# .env.development KLING_ACCESS_KEY="ak_dev_..." KLING_SECRET_KEY="sk_dev_..." # .env.production KLING_ACCESS_KEY="ak_prod_..." KLING_SECRET_KEY="sk_prod_..."
pythonfrom dataclasses import dataclass from typing import Optional @dataclass class TeamMember: name: str email: str role: str # admin, editor, viewer daily_credit_limit: int allowed_models: list[str] @dataclass class TeamConfig: name: str members: list[TeamMember] total_daily_limit: int = 1000 default_model: str = "kling-v2-master" default_mode: str = "standard" def get_member(self, email: str) -> Optional[TeamMember]: return next((m for m in self.members if m.email == email), None) # Example team configuration team = TeamConfig( name="marketing", total_daily_limit=5000, members=[ TeamMember("Alice", "alice@co.com", "admin", 2000, ["kling-v2-6", "kling-v2-master", "kling-v2-5-turbo"]), TeamMember("Bob", "bob@co.com", "editor", 500, ["kling-v2-master", "kling-v2-5-turbo"]), TeamMember("Carol", "carol@co.com", "viewer", 100, ["kling-v2-5-turbo"]), ], )
pythonimport time from collections import defaultdict class TeamQuotaManager: """Enforce per-member and team-wide credit limits.""" def __init__(self, config: TeamConfig): self.config = config self._usage = defaultdict(int) # email -> credits used today self._reset_time = time.time() def _check_reset(self): if time.time() - self._reset_time > 86400: self._usage.clear() self._reset_time = time.time() def authorize(self, email: str, credits_needed: int, model: str) -> bool: self._check_reset() member = self.config.get_member(email) if not member: raise PermissionError(f"Unknown user: {email}") if model not in member.allowed_models: raise PermissionError(f"{email} not authorized for {model}") if self._usage[email] + credits_needed > member.daily_credit_limit: raise RuntimeError(f"{email} exceeds daily limit " f"({self._usage[email]} + {credits_needed} > {member.daily_credit_limit})") team_total = sum(self._usage.values()) + credits_needed if team_total > self.config.total_daily_limit: raise RuntimeError(f"Team daily limit exceeded ({team_total} > {self.config.total_daily_limit})") return True def record_usage(self, email: str, credits: int): self._usage[email] += credits def usage_report(self) -> dict: return { "team_total": sum(self._usage.values()), "team_limit": self.config.total_daily_limit, "by_member": dict(self._usage), }
| Tool | How to Store AK/SK | |------|-------------------| | AWS Secrets Manager | aws secretsmanager create-secret --name kling/prod | | GCP Secret Manager | gcloud secrets create kling-prod | | HashiCorp Vault | vault kv put secret/kling ak=... sk=... | | 1Password CLI | op item create --category login --title "Kling API" |
python# Load from AWS Secrets Manager import boto3 import json def get_kling_credentials(secret_name="kling/prod"): client = boto3.client("secretsmanager") secret = client.get_secret_value(SecretId=secret_name) creds = json.loads(secret["SecretString"]) return creds["access_key"], creds["secret_key"]
pythonclass TeamKlingClient: """Kling client with team-level access control.""" def __init__(self, base_client, quota_manager: TeamQuotaManager): self.client = base_client self.quotas = quota_manager def text_to_video(self, email: str, prompt: str, **kwargs): model = kwargs.get("model", "kling-v2-master") credits = 10 if kwargs.get("mode") != "professional" else 35 self.quotas.authorize(email, credits, model) result = self.client.text_to_video(prompt, **kwargs) self.quotas.record_usage(email, credits) return result
| Case | Status | Duration (ms) | Turns | Tokens | Tool calls | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Without | With | Δ | Without | With | Δ | Without | With | Δ | Without | With | Δ | ||
case-02 | fail→fail | 20,301 | 15,342 | -24% | 1 | 1 | 0% | 3,275 | 3,588 | +10% | 0 | 0 | — |
case-01 | fail→fail | 36,398 | 25,061 | -31% | 1 | 1 | 0% | 4,129 | 6,074 | +47% | 0 | 0 | — |
case-03 | fail→pass | 22,730 | 23,361 | +3% | 1 | 1 | 0% | 3,778 | 5,510 | +46% | 0 | 0 | — |
case-04 | fail→pass | 16,655 | 3,101 | -81% | 1 | 1 | 0% | 827 | 2,009 | +143% | 0 | 0 | — |
case-05 | pass→pass | 11,884 | 7,222 | -39% | 1 | 1 | 0% | 1,234 | 1,880 | +52% | 0 | 0 | — |
case-06 | fail→pass | 8,290 | 9,371 | +13% | 1 | 1 | 0% | 1,570 | 2,271 | +45% | 0 | 0 | — |
case-12 | fail→pass | 17,666 | 9,603 | -46% | 1 | 1 | 0% | 2,450 | 2,722 | +11% | 0 | 0 | — |
case-07 | fail→pass | 14,063 | 11,869 | -16% | 1 | 1 | 0% | 1,970 | 2,934 | +49% | 0 | 0 | — |
case-08 | pass→pass | 14,772 | 13,650 | -8% | 1 | 1 | 0% | 1,747 | 3,119 | +79% | 0 | 0 | — |
case-09 | fail→pass | 30,557 | 10,656 | -65% | 1 | 1 | 0% | 1,142 | 2,688 | +135% | 0 | 0 | — |
case-10 | fail→pass | 18,750 | 16,737 | -11% | 1 | 1 | 0% | 3,275 | 3,667 | +12% | 0 | 0 | — |
case-11 | fail→pass | 14,567 | 5,897 | -60% | 1 | 1 | 0% | 1,909 | 2,639 | +38% | 0 | 0 | — |
case-13 | fail→fail | 14,575 | 11,118 | -24% | 1 | 1 | 0% | 3,139 | 3,659 | +17% | 0 | 0 | — |
case-14 | fail→pass | 10,283 | 8,873 | -14% | 1 | 1 | 0% | 911 | 2,133 | +134% | 0 | 0 | — |
case-15 | fail→fail | 10,694 | 8,792 | -18% | 1 | 1 | 0% | 1,031 | 2,146 | +108% | 0 | 0 | — |
case-16 | fail→pass | 4,221 | 3,506 | -17% | 1 | 1 | 0% | 768 | 1,909 | +149% | 0 | 0 | — |
case-17 | fail→fail | 12,910 | 4,236 | -67% | 1 | 1 | 0% | 1,370 | 2,195 | +60% | 0 | 0 | — |
case-18 | pass→pass | 14,900 | 16,042 | +8% | 1 | 1 | 0% | 2,015 | 3,298 | +64% | 0 | 0 | — |
case-19 | fail→pass | 24,612 | 18,303 | -26% | 1 | 1 | 0% | 3,304 | 3,462 | +5% | 0 | 0 | — |
case-20 | fail→pass | 20,314 | 1,927 | -91% | 1 | 1 | 0% | 1,592 | 1,851 | +16% | 0 | 0 | — |
case-21 | fail→pass | 20,399 | 10,580 | -48% | 1 | 1 | 0% | 3,911 | 3,611 | -8% | 0 | 0 | — |
case-22 | pass→pass | 16,744 | 15,638 | -7% | 1 | 1 | 0% | 2,258 | 3,999 | +77% | 0 | 0 | — |
case-23 | pass→pass | 21,886 | 14,252 | -35% | 1 | 1 | 0% | 3,395 | 4,196 | +24% | 0 | 0 | — |
case-24 | pass→pass | 15,316 | 26,708 | +74% | 1 | 1 | 0% | 3,271 | 5,283 | +62% | 0 | 0 | — |
DecimalAI ran this skill against gemini-3.6-flash twice over the same eval suite — once with the skill loaded and once without — and compared the two runs case by case. 24 cases were attempted, and 22 counted toward the lift figure. The other 2 produced results that are not comparable between the two arms, so they are excluded from the headline rather than averaged into it. The headline lift of +54 percentage points is the difference between those two pass rates over the 22 comparable cases.
Without the skill loaded, the model failed this case. With it loaded, the same prompt on the same model passed. This is one improved case from the latest verified run; every case, including any that regressed, is in the table above.
Other measured skills in the registry, with their headline benchmark lift.