---
title: Credentials checklist
description: Provider-keys checklist for Extentos. Simulator needs none; Phase-4 assistant defaults to the managed gateway; handler calls are BYOK; Meta creds for hardware only.
type: reference
platform: mcp
related:
  - /docs/mcp-server/auth
  - /docs/concepts/ai-gateway
  - /docs/mcp-server/configuration
  - /docs/mcp-server/tools/production
---

Extentos itself needs **no provider keys**. The MCP server, simulator, and code generation work for free with no signup at all (the [auth flow](/docs/mcp-server/auth) handles linking later).

AI shows up in an Extentos app two distinct ways, and only one of them needs a key in your code:

- **The Phase-4 voice assistant runs on the [managed AI gateway](/docs/concepts/ai-gateway) by default — no key in your app.** `glasses.assistant.start(...)` routes through Extentos's gateway on Extentos's provider key; you supply nothing. The opt-out is **BYOK in the dashboard**: upload your OpenAI key in the project's Credentials section and the gateway swaps it in server-side (your app still never holds it). Either way, no provider key lives in your handler for the assistant path. See [the gateway page](/docs/concepts/ai-gateway).
- **Handler-code calls to your own AI provider need your key.** If your handler calls Anthropic / OpenAI / DeepL / etc. directly (e.g., to run a vision model on a captured photo or summarize a transcript outside the assistant), that key lives in the developer's process. Extentos never sees it. The rest of this page is the checklist for **this** path.

Plus one non-AI credential set:

- **Real Meta Ray-Ban hardware** — testing or shipping on physical glasses (not just the browser simulator) requires the developer's own Meta Developer Center registration.

Surface the relevant entries from this page while writing the handler, not at deploy time. If a developer is writing a translation handler, mention DeepL or Google Translate in the same exchange — not three days later when they try to ship.

## Quick decision table

| If your handler calls… | You need… |
|---|---|
| `glasses.assistant.start(...)` (managed gateway, the default) | Nothing — the [gateway](/docs/concepts/ai-gateway) runs on Extentos's key; BYOK is an optional dashboard upload |
| `glasses.audio.speak(...)` (simulator only) | Nothing — Extentos voice proxy handles dev-time TTS |
| `glasses.audio.speak(...)` (real hardware) | Nothing — phone-native TTS; optional premium TTS provider |
| `glasses.audio.transcriptions()` (simulator only) | Nothing — Extentos voice proxy + browser STT |
| `glasses.audio.transcriptions()` (real hardware) | Nothing — phone-native STT |
| An LLM **from your own handler code** (text answer, summarization, classification) | Anthropic, OpenAI, Google Gemini, or another LLM provider |
| A vision API (photo description, OCR via vision) | OpenAI Vision, Google Vision, Anthropic, Azure, or AWS Bedrock |
| A translation API | DeepL, Google Translate, or another translation provider |
| A dedicated OCR API | Google Vision, Azure, or another OCR provider |
| Premium voice synthesis in production | ElevenLabs, Azure Neural, Play.ht, or similar |
| Real Meta Ray-Ban hardware test or ship | Meta Developer Center app registration |

The simulator and managed-assistant paths intentionally need zero credentials — that's the point of Extentos's anonymous-first model and the [managed gateway](/docs/concepts/ai-gateway). Provider keys come up only for direct handler-code AI calls, and Meta credentials only when the developer leaves the simulator for real hardware.

## LLM providers

Only one is required, pick whichever the developer prefers. All have free tiers usable for development.

### Anthropic (Claude)

- **Portal:** [console.anthropic.com/settings/keys](https://console.anthropic.com/settings/keys)
- **Env var convention:** `ANTHROPIC_API_KEY`
- **Free tier:** $5 of credit on signup; pay-as-you-go after.
- **Best for:** Long-context reasoning, tool use, code generation in handlers.

### OpenAI

- **Portal:** [platform.openai.com/api-keys](https://platform.openai.com/api-keys)
- **Env var convention:** `OPENAI_API_KEY`
- **Free tier:** Limited free credits on signup; pay-as-you-go after. Multi-modal (text + vision + speech) under one key.
- **Best for:** Vision through GPT-4 Vision, transcription via Whisper, generic chat.

### Google Gemini

- **Portal:** [aistudio.google.com/app/apikey](https://aistudio.google.com/app/apikey)
- **Env var convention:** `GEMINI_API_KEY`
- **Free tier:** Generous free quota (1500 requests/day on Flash, lower on Pro). Best free option for prototyping.
- **Best for:** Cost-sensitive prototyping, multi-modal, fast iteration before committing to a paid provider.

## Vision APIs

If your app captures photos and the handler needs to interpret them, pick one:

| Provider | Portal | Env var |
|---|---|---|
| OpenAI Vision (GPT-4o) | [platform.openai.com/api-keys](https://platform.openai.com/api-keys) | `OPENAI_API_KEY` |
| Google Vision | [console.cloud.google.com/apis/credentials](https://console.cloud.google.com/apis/credentials) (enable Cloud Vision API) | `GOOGLE_API_KEY` or service account |
| Anthropic Claude Vision | [console.anthropic.com/settings/keys](https://console.anthropic.com/settings/keys) | `ANTHROPIC_API_KEY` |
| Azure Computer Vision | [portal.azure.com](https://portal.azure.com) → Computer Vision resource | `AZURE_VISION_KEY` + endpoint |
| AWS Bedrock (Claude/Nova) | [console.aws.amazon.com/bedrock](https://console.aws.amazon.com/bedrock) | AWS access key + secret + region |

For most apps, just reuse the LLM provider's key — GPT-4o, Claude, and Gemini all do vision under the same key. Separate vision-only providers only matter when you need their specific capabilities (Google's high-accuracy OCR, Azure's domain models).

## Translation

For multilingual apps:

| Provider | Portal | Env var |
|---|---|---|
| DeepL | [deepl.com/pro-api](https://www.deepl.com/pro-api) | `DEEPL_API_KEY` |
| Google Translate | [console.cloud.google.com/apis/credentials](https://console.cloud.google.com/apis/credentials) (enable Translation API) | `GOOGLE_API_KEY` |
| HuggingFace Inference | [huggingface.co/settings/tokens](https://huggingface.co/settings/tokens) | `HF_TOKEN` |

DeepL is generally higher quality for European languages; Google Translate has wider language coverage. HuggingFace Inference works for self-hosted or community models.

## OCR

If the handler reads text out of camera frames:

| Provider | Portal | Env var |
|---|---|---|
| Google Vision (text detection) | [console.cloud.google.com](https://console.cloud.google.com) (enable Cloud Vision API) | `GOOGLE_API_KEY` |
| Azure Computer Vision (Read API) | [portal.azure.com](https://portal.azure.com) | `AZURE_VISION_KEY` + endpoint |
| AWS Textract | [console.aws.amazon.com/textract](https://console.aws.amazon.com/textract) | AWS access key + secret + region |

Most LLMs with vision (GPT-4o, Claude, Gemini) can do OCR-style tasks under their existing key — separate OCR services matter for high-volume document workflows.

## Premium voice synthesis (production)

Optional. Production apps use phone-native TTS by default (`TextToSpeech` on Android, `AVSpeechSynthesizer` on iOS) at zero cost. If the developer wants higher-quality voices:

| Provider | Portal | Env var |
|---|---|---|
| ElevenLabs | [elevenlabs.io/app/settings/api-keys](https://elevenlabs.io/app/settings/api-keys) | `ELEVENLABS_API_KEY` |
| Azure Neural TTS | [portal.azure.com](https://portal.azure.com) → Speech resource | `AZURE_SPEECH_KEY` + region |
| Play.ht | [play.ht/studio/api-access](https://play.ht/studio/api-access) | `PLAYHT_API_KEY` + user ID |

Wire premium voice via `ExtentosConfig.premiumVoice` in the library config — see the configuration reference. Extentos doesn't sit in the runtime path; the library calls the provider directly from the phone.

## Meta Developer Center (real hardware)

**Skip this until the developer is ready to test on physical Meta Ray-Ban glasses.** The browser simulator and `LocalSimTransport` don't need any of it.

When real hardware comes into play:

1. Create a Meta Developer account at [developers.meta.com](https://developers.meta.com).
2. Register a Wearables app under the developer's account.
3. Bind the app to platform-specific identifiers:
   - **Android:** package name + release signing SHA-256.
   - **iOS:** Bundle ID + Team ID + a custom URL scheme of the developer's choosing.
4. Retrieve the **Meta App ID** and **Client Token** from the Meta Developer Center dashboard.
5. Set your Meta credentials in the **AndroidManifest `<meta-data>`** (Android) / **`Info.plist` `MWDAT` dict** (iOS) — the MWDAT SDK reads them from there at init (`Wearables.initialize(applicationContext)` takes only the context). There is no runtime credential-injection path through `ExtentosConfig`.

   ```xml title="Android (AndroidManifest.xml)"
   <application>
       <meta-data android:name="com.meta.wearable.app_id"
                  android:value="@string/meta_app_id" />
       <meta-data android:name="com.meta.wearable.client_token"
                  android:value="@string/meta_client_token" />
   </application>
   ```

   ```xml title="iOS (Info.plist)"
   <key>MWDAT</key>
   <dict>
       <key>MetaAppID</key><string>$(META_APP_ID)</string>
       <key>ClientToken</key><string>$(META_CLIENT_TOKEN)</string>
       <key>TeamID</key><string>$(DEVELOPMENT_TEAM)</string>
   </dict>
   ```

6. Source the values from `local.properties` → string resource (Android dev) or an `.xcconfig` substitution into `Info.plist` (iOS) — never hardcode them in source. The MCP `getCredentialGuide` tool emits the exact manifest/Info.plist entries and the local.properties-first wiring for the developer's platform.

The MCP `getCredentialGuide` tool walks through this interactively with the developer when they call it — that's the agent-facing entry point if step-by-step is preferred over this static reference.

## Voice in the simulator (no keys needed)

The browser simulator's STT and TTS run on Extentos-managed infrastructure (the voice proxy described in [accounts and pricing](/docs/resources/pricing)). Developers don't sign up for Whisper, OpenAI, or any voice provider to use voice in the simulator — that's deliberate, so the first speak/listen experience works out of the box.

Voice in the simulator is unmetered for linked accounts (the browser simulator itself requires sign-in — see [pricing](/docs/resources/pricing)) — there's no separate voice quota. On real hardware, voice runs entirely on the phone (zero Extentos cost, zero provider keys).

## Where to put keys

**Never check provider keys into source control.**

- **Android:** `local.properties` for dev (read at Gradle config time, deterministic across IDE-launch + daemon-reuse), with `System.getenv(...)` as the CI/release fallback baked into the same snippet. The `getCredentialGuide` response embeds the exact `Properties().apply { ... }` block to paste into `app/build.gradle.kts`. Keys surface at runtime via `context.getString(R.string.<keyname>)` (NOT `BuildConfig.X` — that path inlines stale keys across rotations).
- **iOS:** `.xcconfig` files (gitignored) or environment variables on the build runner. Read at runtime via `Bundle.main.object(forInfoDictionaryKey:)`.
- **Local dev:** for the dev-machine path, `local.properties` (Android) / `Secrets.local.xcconfig` (iOS) — both gitignored by default. `.env` files work for non-build runtime use.

For real production deployments, prefer build-time secret injection over runtime env vars where possible — it keeps the keys out of the running app's process memory.

## When to surface this

If you're an AI agent scaffolding an integration for a developer:

- **At handler-scaffolding time**, look at which BYOK providers the handler will call. Surface the matching rows from the [Quick decision table](#quick-decision-table) inline so the developer knows what they'll need before they get deep into handler code.
- **At code-generation time**, call `getCredentialGuide(services, platform)` and apply the returned `build.gradle.kts` snippet directly — the canonical local.properties-first pattern is already baked in.
- **Before the first real-hardware test**, surface the Meta Developer Center section as a separate setup step — it's a longer process (~15-30 min) and the developer wants to do it once, not interleaved with handler code.

Don't dump the full table on a developer who's still in the simulator; it adds noise. The simulator path is meant to need no keys at all.

## Related

- **[Auth](/docs/mcp-server/auth)** — Extentos account auth, separate from provider keys
- **[Configuration](/docs/mcp-server/configuration)** — env vars and config-file settings
- **[Production tools](/docs/mcp-server/tools/production)** — `getCredentialGuide`, `getProductionChecklist`
- **[Pricing](/docs/resources/pricing)** — what the free tier covers
