microsoft/semantic-kernel · error · Exception

Failed to get ephemeral token: {error_text}

Error message

Failed to get ephemeral token: {error_text}

What it means

Before establishing a WebRTC session, the service requests an ephemeral token from OpenAI by POSTing to the token endpoint with the API key and model. If the response status is not 200/201, the error body is wrapped in a bare Exception. The chained except logs and re-raises. This is the auth handshake step that precedes the SDP exchange.

Source

Thrown at python/semantic_kernel/connectors/ai/open_ai/services/_open_ai_realtime.py:906

        Request body: {"session": {"type": "realtime", "model": "<model>"}}
        Response: {"value": "<token>", "expires_at": ..., "session": {...}}
        """
        data = {
            "session": {
                "type": "realtime",
                "model": self.ai_model_id,
            }
        }
        headers, url = self._get_ephemeral_token_headers_and_url()
        headers = prepend_semantic_kernel_to_user_agent(headers)
        try:
            async with (
                ClientSession() as session,
                session.post(url, headers=headers, json=data) as response,
            ):
                if response.status not in [200, 201]:
                    error_text = await response.text()
                    raise Exception(f"Failed to get ephemeral token: {error_text}")

                result = await response.json()
                return result["value"]

        except Exception as e:
            logger.error(f"Failed to get ephemeral token: {e!s}")
            raise

    def _get_ephemeral_token_headers_and_url(self) -> tuple[dict[str, str], str]:
        """Get the headers and URL for the ephemeral token."""
        return {
            "Authorization": f"Bearer {self.client.api_key}",
            "Content-Type": "application/json",
        }, f"{self.client.realtime._client.base_url}/realtime/client_secrets"

    def _get_webrtc_url(self) -> str:
        """Get the WebRTC URL.

View on GitHub (pinned to c028a0c7dc)

Solutions

  1. Verify the OpenAI API key is valid and has realtime model access — test with a simple chat completion first.
  2. Read error_text in the exception to get OpenAI's specific error code/message.
  3. Check that ai_model_id is a supported realtime model.
  4. For 429/5xx, implement exponential backoff retry.
  5. Ensure the account billing is active and within quota.

Example fix

// before
await service.create_session()  # fails at token step
// after
# Verify API key first
import openai
client = openai.AsyncOpenAI(api_key=os.environ['OPENAI_API_KEY'])
# ensure key works, then:
try:
    await service.create_session()
except Exception as e:
    if 'ephemeral token' in str(e):
        # auth issue — check API key and quota
Defensive patterns

Strategy: retry

Validate before calling

null

Type guard

null

Try / catch

import asyncio

for attempt in range(3):
    try:
        await service.create_session()
        break
    except Exception as e:
        if 'ephemeral token' in str(e) and attempt < 2:
            await asyncio.sleep(2 ** attempt)
            continue
        raise

Prevention

When it happens

Trigger: The POST to OpenAI's ephemeral token endpoint returns non-2xx — e.g. 401 (invalid API key), 403 (key lacks realtime access), 404 (model not found), 429 (rate/quota limit). The error_text from the response body is included in the message.

Common situations: Wrong or expired OpenAI API key; API key without realtime API access enabled; quota exceeded; using a model ID that doesn't support realtime; billing issue on the OpenAI account; network connectivity problem reaching the token endpoint.

Related errors


AI-assisted analysis of microsoft/semantic-kernel@c028a0c7dc (2026-08-13). Data as JSON: /api/errors/7ed22be6e0665206. Report an issue: GitHub.