No son alias. Una se convierte en `x-api-key` y la otra en `Authorization: Bearer`; cuando ambas están definidas, puede ganar la que no pretendías usar. La mayoría de los informes de «mi clave es correcta, pero la autenticación falla» contra una URL base personalizada se deben a esto.
El error
# Sent as: x-api-key: <value>
export ANTHROPIC_API_KEY="sk-ant-..."
# Sent as: Authorization: Bearer <value>
export ANTHROPIC_AUTH_TOKEN="sk-kn-..."
# Where those headers go:
export ANTHROPIC_BASE_URL="https://api.kunavo.com"Causas y soluciones de un vistazo
| Causa | Solución |
|---|---|
| La pasarela espera un token bearer; has definido la variable de la clave de API | La mayoría de las pasarelas compatibles con OpenAI autentican mediante `Authorization: Bearer`. Pon la clave de la pasarela en ANTHROPIC_AUTH_TOKEN. |
| Ambas variables están definidas, de proveedores distintos | Un ANTHROPIC_API_KEY antiguo en el perfil del shell puede enviarse junto al token. Anula la variable que no estés usando. |
| La URL base está definida, pero las credenciales no han cambiado | Apuntar a un host nuevo no hace válida allí la clave de un proveedor antiguo. La credencial debe cambiar junto con el host. |
| La variable está definida en un shell distinto del que ejecuta la herramienta | Una exportación en un shell interactivo no llega a un proceso iniciado desde una interfaz gráfica. Verifícalo dentro del mismo entorno. |
Comprueba qué contiene realmente tu entorno
Comprueba ambas variables en el shell que inicia la herramienta antes de cambiar nada. Un porcentaje sorprendente de estas sesiones tiene las dos definidas, a menudo una desde una modificación del perfil de hace meses que nadie recuerda.
for v in ANTHROPIC_API_KEY ANTHROPIC_AUTH_TOKEN ANTHROPIC_BASE_URL; do
printf '%-22s %s\n' "$v" "$(printenv "$v" | cut -c1-12)"
done
# Prefixes tell you the provider at a glance:
# sk-ant- Anthropic direct
# sk-kn- KunavoDefine el par que corresponde a tu host y anula el otro
Trata el host y la credencial como una sola unidad. Frente a una URL base de terceros, normalmente es el token bearer junto con la URL base, con la clave de API directa anulada explícitamente para que no se recoja por accidente.
unset ANTHROPIC_API_KEY
export ANTHROPIC_AUTH_TOKEN="sk-kn-..."
export ANTHROPIC_BASE_URL="https://api.kunavo.com"
# On Kunavo, pin served models too: Claude Code's default and its opus and
# sonnet aliases follow Anthropic's newest models, and the sonnet alias asks
# for Sonnet 5.5, which Kunavo does not serve — unpinned, that request 404s.
export ANTHROPIC_MODEL="claude-sonnet-5"
export ANTHROPIC_DEFAULT_OPUS_MODEL="claude-opus-5-5"
export ANTHROPIC_DEFAULT_SONNET_MODEL="claude-sonnet-5"
export ANTHROPIC_DEFAULT_HAIKU_MODEL="claude-haiku-4-5"
claudeConfirma lo que se envía por la red, no lo que crees
Si la autenticación sigue fallando, elimina el entorno de la ecuación: emite manualmente la solicitud con el encabezado que crees que se está enviando. Si aquí obtienes 200 y la herramienta falla, significa que la herramienta no está leyendo la variable que definiste; lo más habitual es que use otro shell o que un archivo de configuración la sobrescriba.
curl -s -o /dev/null -w '%{http_code}\n' \
"$ANTHROPIC_BASE_URL/v1/models" \
-H "Authorization: Bearer $ANTHROPIC_AUTH_TOKEN"Si llamas a través de Kunavo
Kunavo lee la clave tanto desde `Authorization: Bearer` como desde `x-api-key`, así que el encabezado no es lo que decide el resultado. Con Claude Code, el par funcional sigue siendo ANTHROPIC_AUTH_TOKEN más ANTHROPIC_BASE_URL: el token funciona sin la aprobación única que necesita ANTHROPIC_API_KEY. ANTHROPIC_API_KEY debe estar anulada y no quedar definida, porque un valor antiguo allí es la causa más común de una sesión que parece configurada y aun así rechaza las solicitudes. La misma clave `sk-kn-` funciona sin cambios como token bearer al estilo de OpenAI contra /v1/chat/completions, por lo que una sola credencial cubre ambos formatos. La configuración completa, incluidos los nombres de modelo que debes usar, está en nuestra guía de errores 401 de Claude Code.
Preguntas frecuentes
Si ambas están definidas, ¿cuál gana?
No dependas de la respuesta: es una regla de precedencia que ha cambiado entre versiones y difiere entre SDK. Define exactamente una y anula la otra; es la única configuración que se comporta igual en todas partes.
¿Puedo usar ANTHROPIC_AUTH_TOKEN directamente con Anthropic?
La propia API de Anthropic autentica mediante x-api-key, por lo que una clave directa de Anthropic debe ir en ANTHROPIC_API_KEY. La variable del token existe para hosts que esperan una credencial bearer.
¿El SDK usa las mismas variables?
Los SDK de Python y TypeScript leen ANTHROPIC_API_KEY y envían x-api-key. Si diriges un SDK a una pasarela con autenticación bearer, pasa la credencial explícitamente en lugar de depender del entorno.
Guías relacionadas
- Claude Code «API Error: 401 authentication_error» con una URL base personalizada: todas las causas
- Claude API 401 authentication_error / invalid x-api-key: todas las causas
- API compatible con OpenAI que devuelve 401/403: errores habituales de base_url y headers
- “Tu organización ha desactivado el acceso a la suscripción de Claude para Claude Code”: las tres causas y qué funciona
Encontrarás más detalles sobre el significado de los errores en referencia de errores; obtener una clave lleva un minuto mediante registro y la guía de autenticación.