Skip to content

Commit fb07141

Browse files
Merge pull request #950 from MarvinDontPanic/fix/elevenlabs-detect-endpoint
Better endpoint for key validation — the /v1/voices endpoint is more reliable across tier levels. Merged, thanks!
2 parents 2527e13 + 69c8fa6 commit fb07141

File tree

1 file changed

+17
-1
lines changed
  • Releases/v4.0.3/.claude/PAI-Install/engine

1 file changed

+17
-1
lines changed

Releases/v4.0.3/.claude/PAI-Install/engine/detect.ts

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -152,15 +152,31 @@ export function detectSystem(): DetectionResult {
152152

153153
/**
154154
* Validate an ElevenLabs API key.
155+
* Uses /v1/voices endpoint (requires only xi-api-key header, no specific scope)
156+
* instead of /v1/user (requires user_read permission, which many keys lack).
157+
* Also handles 401 with missing_permissions as "valid key, limited scope" —
158+
* TTS works fine with a known voice_id even without voices_read permission.
155159
*/
156160
export async function validateElevenLabsKey(key: string): Promise<{ valid: boolean; error?: string }> {
157161
try {
158-
const res = await fetch("https://api.elevenlabs.io/v1/user", {
162+
const res = await fetch("https://api.elevenlabs.io/v1/voices", {
159163
headers: { "xi-api-key": key },
160164
signal: AbortSignal.timeout(10000),
161165
});
162166

163167
if (res.ok) return { valid: true };
168+
169+
// 401 with missing_permissions means the key IS valid but lacks a specific scope.
170+
// TTS still works (doesn't need voices_read to use a known voice_id).
171+
if (res.status === 401) {
172+
try {
173+
const body = await res.json();
174+
if (body?.detail?.status === "missing_permissions") {
175+
return { valid: true };
176+
}
177+
} catch { /* fall through to error */ }
178+
}
179+
164180
return { valid: false, error: `HTTP ${res.status}` };
165181
} catch (e: any) {
166182
return { valid: false, error: e.message || "Network error" };

0 commit comments

Comments
 (0)