{"record":{"id":"7ed22be6e0665206","repo":"microsoft/semantic-kernel","slug":"failed-to-get-ephemeral-token-error-text","errorCode":null,"errorMessage":"Failed to get ephemeral token: {error_text}","messagePattern":"Failed to get ephemeral token: (.+?)","errorType":"exception","errorClass":"Exception","httpStatus":null,"severity":"error","filePath":"python/semantic_kernel/connectors/ai/open_ai/services/_open_ai_realtime.py","lineNumber":906,"sourceCode":"        Request body: {\"session\": {\"type\": \"realtime\", \"model\": \"<model>\"}}\n        Response: {\"value\": \"<token>\", \"expires_at\": ..., \"session\": {...}}\n        \"\"\"\n        data = {\n            \"session\": {\n                \"type\": \"realtime\",\n                \"model\": self.ai_model_id,\n            }\n        }\n        headers, url = self._get_ephemeral_token_headers_and_url()\n        headers = prepend_semantic_kernel_to_user_agent(headers)\n        try:\n            async with (\n                ClientSession() as session,\n                session.post(url, headers=headers, json=data) as response,\n            ):\n                if response.status not in [200, 201]:\n                    error_text = await response.text()\n                    raise Exception(f\"Failed to get ephemeral token: {error_text}\")\n\n                result = await response.json()\n                return result[\"value\"]\n\n        except Exception as e:\n            logger.error(f\"Failed to get ephemeral token: {e!s}\")\n            raise\n\n    def _get_ephemeral_token_headers_and_url(self) -> tuple[dict[str, str], str]:\n        \"\"\"Get the headers and URL for the ephemeral token.\"\"\"\n        return {\n            \"Authorization\": f\"Bearer {self.client.api_key}\",\n            \"Content-Type\": \"application/json\",\n        }, f\"{self.client.realtime._client.base_url}/realtime/client_secrets\"\n\n    def _get_webrtc_url(self) -> str:\n        \"\"\"Get the WebRTC URL.\n","sourceCodeStart":888,"sourceCodeEnd":924,"githubUrl":"https://github.com/microsoft/semantic-kernel/blob/c028a0c7dc4f0814cdcbaba9d998f187a41197bf/python/semantic_kernel/connectors/ai/open_ai/services/_open_ai_realtime.py#L888-L924","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Verify the OpenAI API key is valid and has realtime model access — test with a simple chat completion first.","Read error_text in the exception to get OpenAI's specific error code/message.","Check that ai_model_id is a supported realtime model.","For 429/5xx, implement exponential backoff retry.","Ensure the account billing is active and within quota."],"exampleFix":"// before\nawait service.create_session()  # fails at token step\n// after\n# Verify API key first\nimport openai\nclient = openai.AsyncOpenAI(api_key=os.environ['OPENAI_API_KEY'])\n# ensure key works, then:\ntry:\n    await service.create_session()\nexcept Exception as e:\n    if 'ephemeral token' in str(e):\n        # auth issue — check API key and quota","handlingStrategy":"retry","validationCode":"null","typeGuard":"null","tryCatchPattern":"import asyncio\n\nfor attempt in range(3):\n    try:\n        await service.create_session()\n        break\n    except Exception as e:\n        if 'ephemeral token' in str(e) and attempt < 2:\n            await asyncio.sleep(2 ** attempt)\n            continue\n        raise","preventionTips":["Verify the OpenAI API key is valid with a simple API call before using realtime.","Ensure the API key's account has realtime model access and active billing.","Implement exponential backoff for rate-limit (429) responses.","Log the full error_text from the response for diagnosis."],"tags":["openai","realtime","authentication","api-key","network","semantic-kernel"],"backgroundTag":null,"analyzedSha":"c028a0c7dc4f0814cdcbaba9d998f187a41197bf","analyzedAt":"2026-08-13T13:48:05.040Z","schemaVersion":2},"datasetVersion":"2026-08-13T14:17:21.547Z"}