Fix Widget SDK issues
Use this guide as a checklist when your widget integration fails to load, connect, or access media. Each section includes the exact error or symptom, the root cause, and the fix.
CORS errors when fetching session config
Error
Access to fetch at 'http://localhost:3000/api/orga-session' from origin 'http://localhost:5173' has been blocked by CORS policyOr in the browser console:
CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resourceCause – Your backend endpoint doesn’t allow cross-origin requests from the widget’s domain. This is common when the widget is hosted on a different origin than your backend (e.g., widget on example.com calling backend at api.example.com).
Fix
Configure your backend to allow CORS requests. The exact implementation depends on your backend framework:
Next.js API Route:
import { NextResponse } from 'next/server';
import { OrgaAI } from '@orga-ai/node';
const orgaAI = new OrgaAI({
apiKey: process.env.ORGA_API_KEY!,
});
export async function GET(request: Request) {
// Handle CORS preflight
if (request.method === 'OPTIONS') {
return new NextResponse(null, {
status: 200,
headers: {
'Access-Control-Allow-Origin': '*', // Or specific origin: 'https://yourdomain.com'
'Access-Control-Allow-Methods': 'GET, OPTIONS',
'Access-Control-Allow-Headers': 'Content-Type',
},
});
}
try {
const sessionConfig = await orgaAI.getSessionConfig();
return NextResponse.json(sessionConfig, {
headers: {
'Access-Control-Allow-Origin': '*', // Or specific origin
'Access-Control-Allow-Methods': 'GET, OPTIONS',
'Access-Control-Allow-Headers': 'Content-Type',
},
});
} catch (error) {
console.error('OrgaAI session error', error);
return NextResponse.json(
{ error: 'Failed to fetch session config' },
{
status: 500,
headers: {
'Access-Control-Allow-Origin': '*',
},
},
);
}
}Express.js:
import express from 'express';
import cors from 'cors';
import { OrgaAI } from '@orga-ai/node';
const app = express();
app.use(cors({
origin: '*', // Or specific origins: ['https://yourdomain.com', 'https://app.yourdomain.com']
methods: ['GET', 'OPTIONS'],
}));
const orgaAI = new OrgaAI({
apiKey: process.env.ORGA_API_KEY!,
});
app.get('/api/orga-session', async (_req, res) => {
try {
const sessionConfig = await orgaAI.getSessionConfig();
res.json(sessionConfig);
} catch (error) {
console.error('Failed to get session config', error);
res.status(500).json({ error: 'Internal server error' });
}
});In production, replace '*' with specific allowed origins for better security. Only allow origins that actually host your widget.
Camera or microphone permissions denied immediately
Symptom – When you try to enable the camera or microphone after connecting, the browser immediately denies permission without showing a prompt. The widget shows an error or the controls don’t activate.
Cause – Your browser’s default permission setting for camera/microphone is set to “Block” instead of “Ask” (or “Prompt”). This prevents the browser from even showing the permission dialog.
Fix
Chrome / Edge
- Click the lock icon (or info icon) in the address bar.
- Find Camera and Microphone in the permissions list.
- Change both from Block to Ask (or Allow for trusted sites).
- Refresh the page and try again.
Alternatively, go to:
- Chrome:
chrome://settings/content/cameraandchrome://settings/content/microphone - Edge:
edge://settings/content/cameraandedge://settings/content/microphone
Set the default behavior to “Ask before accessing” (not “Block”).
Firefox
- Click the lock icon in the address bar.
- Click More Information → Permissions tab.
- Find Use the Camera and Use the Microphone.
- Change from Block to Ask or Allow.
- Refresh the page.
Or go to about:preferences#privacy and scroll to Permissions → Settings → ensure camera/microphone default is “Ask”.
Safari
- Go to Safari → Settings → Websites.
- Select Camera and Microphone from the left sidebar.
- For your site, change from Deny to Ask or Allow.
- Refresh the page.
Verify the fix
After changing the settings, refresh your page and try starting a session again. You should see the browser’s permission prompt appear.
If you’re testing on localhost, most browsers allow media access by default. If you’re still seeing issues on localhost, check that your site is served over HTTPS or that localhost is explicitly allowed in your browser settings.
Backend returns 401 or 500 errors
Symptom – The widget shows an error message when trying to start a session, or the browser console shows:
Failed to fetch session configOr your backend logs show:
401 UnauthorizedCause – Your backend endpoint is missing the Orga API key, has an invalid key, or isn’t properly configured.
Fix
1. Verify environment variable
Ensure your .env.local (or .env) file contains a valid API key:
ORGA_API_KEY=sk_orga_ai_*****************************2. Restart your dev server
Environment variables are only loaded when the server starts. After adding or changing .env.local:
# Stop your server (Ctrl+C), then restart
pnpm dev
# or
npm run dev3. Verify the API key is loaded
Add a temporary log to confirm the key is being read:
import { OrgaAI } from '@orga-ai/node';
// Temporary debug log (remove after verification)
console.log('API Key present:', !!process.env.ORGA_API_KEY);
const orgaAI = new OrgaAI({
apiKey: process.env.ORGA_API_KEY!,
});If the log shows false, your environment variable isn’t being loaded. Check:
- File is named exactly
.env.local(not.env.local.txtor similar) - File is in the project root (same directory as
package.json) - Server was restarted after creating/modifying the file
4. Test the backend endpoint directly
Use curl or your browser to verify the endpoint returns valid JSON:
curl http://localhost:3000/api/orga-sessionExpected response:
{
"ephemeralToken": "eyJhbGciOi...",
"iceServers": [
{ "urls": "stun:stun1.l.google.com:19302" },
{
"urls": ["turn:turn.orga-ai.com:3478"],
"username": "6b4c...",
"credential": "0433..."
}
]
}If you see an error or empty response, check your server logs for the specific error message.
5. Verify API key format
Your Orga API key should:
- Start with
sk_orga_ai_ - Be the full key (not truncated)
- Be copied from the Orga dashboard without extra spaces or newlines
Widget doesn’t appear on the page
Symptom – You’ve added the CDN script or initialized the widget, but nothing appears on the page.
Fix
CDN usage
- Verify the script loads – Check the browser console for script load errors.
- Ensure the mount point exists – Add
<div data-orga-widget></div>to your HTML before the initialization script runs. - Wait for script to load – If using
async, the script might not be ready whenOrgaWidget.initWidget()runs. Use:
<script src="https://orga-cdn.vercel.app/init.global.js"></script>
<script>
// Wait for script to load
window.addEventListener('load', () => {
if (window.OrgaWidget) {
OrgaWidget.initWidget({
fetchSessionConfig: () =>
fetch('/api/orga-session').then((res) => res.json()),
});
}
});
</script>npm / React usage
- Verify the component renders – Ensure
<OrgaWidgetClient />is included in your layout and the component actually renders. - Check for React errors – Look for errors in the browser console that might prevent the component from mounting.
- Verify the mount point – The component must return
<div data-orga-widget />for the widget to attach.
'use client';
import { useEffect } from 'react';
import { initWidget } from '@orga-ai/widget';
export const OrgaWidgetClient = () => {
useEffect(() => {
initWidget({
fetchSessionConfig: () =>
fetch('/api/orga-session').then((res) => res.json()),
});
}, []);
// This div is required for the widget to mount
return <div data-orga-widget />;
};Session connects but no audio/video
Symptom – The widget shows “Connected” but you don’t hear the AI or see video streams.
Fix
- Check browser console – Look for WebRTC errors or media stream errors.
- Verify media permissions – Ensure camera and microphone permissions are granted (see Camera or microphone permissions denied above).
- Check network – WebRTC requires stable connectivity. Test on a reliable network.
- Verify ICE servers – Your backend must return valid
iceServersin the session config. Check that your backend endpoint includes TURN servers for users behind firewalls.
General debugging tips
- Enable verbose logging in the widget:
initWidget({
fetchSessionConfig: () => fetch('/api/orga-session').then((res) => res.json()),
logLevel: 'debug', // Shows detailed connection and media logs
});- Check the browser’s Network tab to verify the
fetchSessionConfigcall succeeds and returns valid JSON. - Use the browser’s Application/Storage tab to verify camera/microphone permissions for your domain.
- Re-run the Widget tutorial to confirm setup order.
Still blocked? Open an issue in the Orga AI GitHub repo or check the main troubleshooting page for SDK-specific issues.