Skip to content

Anonymous API key ('anonymous') returns 'Invalid token' for chat completions #315

@konard

Description

@konard

Summary

Using apiKey: 'anonymous' (as defined in ANONYMOUS_API_KEY constant in packages/kilo-gateway/src/api/constants.ts) for chat completions returns HTTP 401 with {"error":"Invalid token (uuid)","success":false}.

The same anonymous key does work for the models listing endpoint (/api/openrouter/models), but does not work for chat completions (/api/openrouter/chat/completions).

Reproduction Steps

# This works (models listing):
curl -s "https://api.kilo.ai/api/openrouter/models" \
  -H "Authorization: Bearer anonymous" | head -100
# Returns model list successfully

# This fails (chat completions):
curl -s "https://api.kilo.ai/api/openrouter/chat/completions" \
  -H "Authorization: Bearer anonymous" \
  -H "Content-Type: application/json" \
  -H "User-Agent: opencode-kilo-provider" \
  -H "X-KILOCODE-EDITORNAME: Kilo CLI" \
  -d '{"model":"z-ai/glm-5:free","messages":[{"role":"user","content":"hello"}],"max_tokens":10}'
# Returns: {"error":"Invalid token (uuid)","success":false}

Expected Behavior

Free models (those with 0 pricing) should be accessible using the anonymous API key, consistent with the code in:

  • packages/kilo-gateway/src/api/constants.ts which defines ANONYMOUS_API_KEY = "anonymous"
  • packages/kilo-gateway/src/loader.ts which sets apiKey: "anonymous" when no auth is available
  • packages/kilo-gateway/src/provider.ts which uses ANONYMOUS_API_KEY as fallback

Actual Behavior

The Kilo API backend rejects the anonymous token with HTTP 401 for chat completion requests. The UUID in the error message appears to be a request ID, not the token itself.

Workaround

Users must authenticate via the device auth flow to get a real token, even for free models. This works correctly:

# Initiate device auth
curl -s -X POST "https://api.kilo.ai/api/device-auth/codes" \
  -H "Content-Type: application/json"
# Then complete the flow at the returned URL

Environment

Suggestion

If anonymous access to free models is intended to work (as the client-side code suggests), the backend should accept the "anonymous" token for free model completions. If anonymous access is intentionally disabled, consider:

  1. Updating ANONYMOUS_API_KEY constant and loader to clearly indicate auth is required
  2. Returning a more descriptive error message like "Authentication required. Run device auth to access free models."
  3. Updating the README/docs to clarify that device auth is required even for free models

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions