PageSourceSearch

https://litellm.vercel.app/assets/js/6405c95c.2b865a3c.js

js litellm.vercel.app collected 2026-10-03 07:18:18 UTC 28,620 bytes, 1 lines download raw bytes

1"use strict";(globalThis.webpackChunkmy_website=globalThis.webpackChunkmy_website||[]).push([[9980],{2427(e,n,l){l.r(n),l.d(n,{assets:()=>d,contentTitle:()=>c,default:()=>b,frontMatter:()=>o,metadata:()=>a,toc:()=>g});let a=JSON.parse('{"id":"realtime","title":"/realtime","description":"Use this to loadbalance across Azure + OpenAI + xAI and more.","source":"@site/docs/realtime.md","sourceDirName":".","slug":"/realtime","permalink":"/docs/realtime","draft":false,"unlisted":false,"tags":[],"version":"current","frontMatter":{},"sidebar":"tutorialSidebar","previous":{"title":"Guardrails on Pass-Through Endpoints","permalink":"/docs/proxy/pass_through_guardrails"},"next":{"title":"/realtime - WebRTC Support","permalink":"/docs/proxy/realtime_webrtc"}}');var i=l(74848),s=l(28453),t=l(53720),r=l(5400);let o={rawMarkdownB64:"aW1wb3J0IFRhYnMgZnJvbSAnQHRoZW1lL1RhYnMnOwppbXBvcnQgVGFiSXRlbSBmcm9tICdAdGhlbWUvVGFiSXRlbSc7CgojIC9yZWFsdGltZQoKVXNlIHRoaXMgdG8gbG9hZGJhbGFuY2UgYWNyb3NzIEF6dXJlICsgT3BlbkFJICsgeEFJIGFuZCBtb3JlLiAKClN1cHBvcnRlZCBQcm92aWRlcnM6Ci0gT3BlbkFJCi0gQXp1cmUKLSB4QUkgKFtzZWUgZnVsbCBkb2NzXSgvZG9jcy9wcm92aWRlcnMveGFpX3JlYWx0aW1lKSkKLSBHb29nbGUgQUkgU3R1ZGlvIChHZW1pbmkpCi0gVmVydGV4IEFJCi0gVmVydGV4IEFJIENoaXJwLCB0cmFuc2NyaXB0aW9uIG9ubHkgKFtzZWUgZnVsbCBkb2NzXSgvZG9jcy9wcm92aWRlcnMvdmVydGV4X3RyYW5zY3JpcHRpb24jY2hpcnAtcmVhbHRpbWUtdHJhbnNjcmlwdGlvbikpCi0gQmVkcm9jawotIE1ldGEgTXVzZSBWb2ljZSwgdHJhbnNjcmlwdGlvbiBvbmx5IChbc2VlIGZ1bGwgZG9jc10oL2RvY3MvcHJvdmlkZXJzL21ldGEjbXVzZS12b2ljZS1yZWFsdGltZS10cmFuc2NyaXB0aW9uKSkKCiMjIFByb3h5IFVzYWdlCgojIyMgQWRkIG1vZGVsIHRvIGNvbmZpZyAKCgo8VGFicz4KPFRhYkl0ZW0gdmFsdWU9Im9wZW5haSIgbGFiZWw9Ik9wZW5BSSI+CgpgYGB5YW1sCm1vZGVsX2xpc3Q6CiAgLSBtb2RlbF9uYW1lOiBvcGVuYWktZ3B0LTRvLXJlYWx0aW1lLWF1ZGlvCiAgICBsaXRlbGxtX3BhcmFtczoKICAgICAgbW9kZWw6IG9wZW5haS9ncHQtNG8tcmVhbHRpbWUtcHJldmlldy0yMDI0LTEwLTAxCiAgICAgIGFwaV9rZXk6IG9zLmVudmlyb24vT1BFTkFJX0FQSV9LRVkKICAgIG1vZGVsX2luZm86CiAgICAgIG1vZGU6IHJlYWx0aW1lCmBgYAo8L1RhYkl0ZW0+CjxUYWJJdGVtIHZhbHVlPSJvcGVuYWkrYXp1cmUiIGxhYmVsPSJPcGVuQUkgKyBBenVyZSI+CgpgYGB5YW1sCm1vZGVsX2xpc3Q6CiAgLSBtb2RlbF9uYW1lOiBhenVyZS1ncHQtNG8tcmVhbHRpbWUtYXVkaW8KICAgIGxpdGVsbG1fcGFyYW1zOgogICAgICBtb2RlbDogYXp1cmUvZ3B0LTRvLXJlYWx0aW1lLXByZXZpZXcKICAgICAgYXBpX2tleTogb3MuZW52aXJvbi9BWlVSRV9TV0VERU5fQVBJX0tFWQogICAgICBhcGlfYmFzZTogb3MuZW52aXJvbi9BWlVSRV9TV0VERU5fQVBJX0JBU0UKCiAgLSBtb2RlbF9uYW1lOiBhenVyZS1ncHQtcmVhbHRpbWUKICAgIGxpdGVsbG1fcGFyYW1zOgogICAgICBtb2RlbDogYXp1cmUvZ3B0LXJlYWx0aW1lCiAgICAgIGFwaV9rZXk6IG9zLmVudmlyb24vQVpVUkVfQVBJX0tFWQogICAgICBhcGlfYmFzZTogb3MuZW52aXJvbi9BWlVSRV9BUElfQkFTRQogICAgbW9kZWxfaW5mbzoKICAgICAgbW9kZTogcmVhbHRpbWUKCiAgLSBtb2RlbF9uYW1lOiBvcGVuYWktZ3B0LTRvLXJlYWx0aW1lLWF1ZGlvCiAgICBsaXRlbGxtX3BhcmFtczoKICAgICAgbW9kZWw6IG9wZW5haS9ncHQtNG8tcmVhbHRpbWUtcHJldmlldy0yMDI0LTEwLTAxCiAgICAgIGFwaV9rZXk6IG9zLmVudmlyb24vT1BFTkFJX0FQSV9LRVkKYGBgCgo8L1RhYkl0ZW0+CjxUYWJJdGVtIHZhbHVlPSJ4YWkiIGxhYmVsPSJ4QUkgR3JvayBWb2ljZSBBZ2VudCI+CgpgYGB5YW1sCm1vZGVsX2xpc3Q6CiAgLSBtb2RlbF9uYW1lOiBncm9rLXZvaWNlLWFnZW50CiAgICBsaXRlbGxtX3BhcmFtczoKICAgICAgbW9kZWw6IHhhaS9ncm9rLXZvaWNlLWxhdGVzdAogICAgICBhcGlfa2V5OiBvcy5lbnZpcm9uL1hBSV9BUElfS0VZCiAgICBtb2RlbF9pbmZvOgogICAgICBtb2RlOiByZWFsdGltZQpgYGAKCioqW1NlZSBmdWxsIHhBSSBSZWFsdGltZSBkb2N1bWVudGF0aW9uIOKGkl0oL2RvY3MvcHJvdmlkZXJzL3hhaV9yZWFsdGltZSkqKgoKPC9UYWJJdGVtPgo8L1RhYnM+CgojIyMgU3RhcnQgcHJveHkgCgpgYGBiYXNoCmxpdGVsbG0gLS1jb25maWcgL3BhdGgvdG8vY29uZmlnLnlhbWwgCgojIFJVTk5JTkcgb24gaHR0cDovLzAuMC4wLjA6NDAwMApgYGAKCiMjIyBUZXN0IAoKUnVuIHRoaXMgc2NyaXB0IHVzaW5nIG5vZGUgLSBgbm9kZSB0ZXN0LmpzYAoKYGBganMKLy8gdGVzdC5qcwpjb25zdCBXZWJTb2NrZXQgPSByZXF1aXJlKCJ3cyIpOwoKY29uc3QgdXJsID0gIndzOi8vMC4wLjAuMDo0MDAwL3YxL3JlYWx0aW1lP21vZGVsPW9wZW5haS1ncHQtNG8tcmVhbHRpbWUtYXVkaW8iOwovLyBjb25zdCB1cmwgPSAid3NzOi8vbXktYXp1cmUtZW5kcG9pbnQub3BlbmFpLmF6dXJlLmNvbS9vcGVuYWkvcmVhbHRpbWU/YXBpLXZlcnNpb249MjAyNC0xMC0wMS1wcmV2aWV3JmRlcGxveW1lbnQ9Z3B0LTRvLXJlYWx0aW1lLXByZXZpZXciOwpjb25zdCB3cyA9IG5ldyBXZWJTb2NrZXQodXJsLCB7CiAgICBoZWFkZXJzOiB7CiAgICAgICAgImFwaS1rZXkiOiBgc2stPHlvdXItbGl0ZWxsbS1hcGkta2V5PmAsCiAgICAgICAgIk9wZW5BSS1CZXRhIjogInJlYWx0aW1lPXYxIiwKICAgIH0sCn0pOwoKd3Mub24oIm9wZW4iLCBmdW5jdGlvbiBvcGVuKCkgewogICAgY29uc29sZS5sb2coIkNvbm5lY3RlZCB0byBzZXJ2ZXIuIik7CiAgICB3cy5zZW5kKEpTT04uc3RyaW5naWZ5KHsKICAgICAgICB0eX
1BlOiAicmVzcG9uc2UuY3JlYXRlIiwKICAgICAgICByZXNwb25zZTogewogICAgICAgICAgICBtb2RhbGl0aWVzOiBbInRleHQiXSwKICAgICAgICAgICAgaW5zdHJ1Y3Rpb25zOiAiUGxlYXNlIGFzc2lzdCB0aGUgdXNlci4iLAogICAgICAgIH0KICAgIH0pKTsKfSk7Cgp3cy5vbigibWVzc2FnZSIsIGZ1bmN0aW9uIGluY29taW5nKG1lc3NhZ2UpIHsKICAgIGNvbnNvbGUubG9nKEpTT04ucGFyc2UobWVzc2FnZS50b1N0cmluZygpKSk7Cn0pOwoKd3Mub24oImVycm9yIiwgZnVuY3Rpb24gaGFuZGxlRXJyb3IoZXJyb3IpIHsKICAgIGNvbnNvbGUuZXJyb3IoIkVycm9yOiAiLCBlcnJvcik7Cn0pOwpgYGAKCiMjIEF6dXJlOiBHQSB2cyBiZXRhIHJlYWx0aW1lIHByb3RvY29sCgpBenVyZSBleHBvc2VzIHR3byByZWFsdGltZSB1cHN0cmVhbXMuIFRoZSBHQSBlbmRwb2ludCAoYC9vcGVuYWkvdjEvcmVhbHRpbWU/bW9kZWw9PGRlcGxveW1lbnQ+YCkgc3BlYWtzIHRoZSBHQSBldmVudCBzY2hlbWEgKGBzZXNzaW9uLnR5cGVgLCBgb3V0cHV0X21vZGFsaXRpZXNgLCBuZXN0ZWQgYGF1ZGlvYCksIGFuZCB0aGUgb2xkZXIgYmV0YSBlbmRwb2ludCAoYC9vcGVuYWkvcmVhbHRpbWU/YXBpLXZlcnNpb249MjAyNC0xMC0wMS1wcmV2aWV3JmRlcGxveW1lbnQ9PGRlcGxveW1lbnQ+YCkgc3BlYWtzIHRoZSBiZXRhIHNjaGVtYSAoYG1vZGFsaXRpZXNgLCBgdm9pY2VgLCBmbGF0IGF1ZGlvIGZvcm1hdHMpLiBTZW5kaW5nIGEgR0Etc2hhcGVkIGBzZXNzaW9uLnVwZGF0ZWAgdG8gdGhlIGJldGEgZW5kcG9pbnQgZmFpbHMgd2l0aCBgVW5rbm93biBwYXJhbWV0ZXI6ICdzZXNzaW9uLnR5cGUnYAoKTGl0ZUxMTSBwaWNrcyB0aGUgdXBzdHJlYW0gZnJvbSB0aGUgY2xpZW50IGNvbm5lY3Rpb24uIEEgY2xpZW50IHRoYXQgc2VuZHMgdGhlIGBPcGVuQUktQmV0YTogcmVhbHRpbWU9djFgIGhlYWRlciAodGhlIG9wZW5haSBTREsncyBgY2xpZW50LmJldGEucmVhbHRpbWUuY29ubmVjdGApIGlzIGJyaWRnZWQgdG8gdGhlIGJldGEgZW5kcG9pbnQuIEEgY2xpZW50IHdpdGhvdXQgdGhhdCBoZWFkZXIgKHRoZSBvcGVuYWkgU0RLJ3MgYGNsaWVudC5yZWFsdGltZS5jb25uZWN0YCwgYW5kIG1vc3Qgdm9pY2UgYWdlbnQgZnJhbWV3b3JrcykgaXMgYnJpZGdlZCB0byB0aGUgR0EgZW5kcG9pbnQuIFRyYW5zY3JpcHRpb24gc2Vzc2lvbnMgKGBpbnRlbnQ9dHJhbnNjcmlwdGlvbmApIGFsd2F5cyB1c2UgR0EKCmBgYHB5dGhvbgpmcm9tIG9wZW5haSBpbXBvcnQgQXN5bmNPcGVuQUkKCmNsaWVudCA9IEFzeW5jT3BlbkFJKGJhc2VfdXJsPSJodHRwOi8vMC4wLjAuMDo0MDAwIiwgYXBpX2tleT0ic2stMTIzNCIpCgphc3luYyB3aXRoIGNsaWVudC5yZWFsdGltZS5jb25uZWN0KG1vZGVsPSJhenVyZS1ncHQtcmVhbHRpbWUiKSBhcyBjb25uZWN0aW9uOgogICAgYXdhaXQgY29ubmVjdGlvbi5zZXNzaW9uLnVwZGF0ZSgKICAgICAgICBzZXNzaW9uPXsidHlwZSI6ICJyZWFsdGltZSIsICJvdXRwdXRfbW9kYWxpdGllcyI6IFsiYXVkaW8iXSwgImluc3RydWN0aW9ucyI6ICJQbGVhc2UgYXNzaXN0IHRoZSB1c2VyLiJ9CiAgICApCiAgICBhc3luYyBmb3IgZXZlbnQgaW4gY29ubmVjdGlvbjoKICAgICAgICBwcmludChldmVudC50eXBlKQogICAgICAgIGlmIGV2ZW50LnR5cGUgPT0gInNlc3Npb24udXBkYXRlZCI6CiAgICAgICAgICAgIGJyZWFrCmBgYAoKVG8gcGluIG9uZSBwcm90b2NvbCByZWdhcmRsZXNzIG9mIHdoYXQgdGhlIGNsaWVudCBzZW5kcywgc2V0IGByZWFsdGltZV9wcm90b2NvbGAgb24gdGhlIGRlcGxveW1lbnQgb3IgYExJVEVMTE1fQVpVUkVfUkVBTFRJTUVfUFJPVE9DT0xgIGluIHRoZSBwcm94eSdzIGVudmlyb25tZW50LiBUaGUgZGVwbG95bWVudCBzZXR0aW5nIHdpbnMgb3ZlciB0aGUgZW52aXJvbm1lbnQgdmFyaWFibGUsIGFuZCBib3RoIHdpbiBvdmVyIHRoZSBjbGllbnQgaGVhZGVyLiBUaGUgcmVhbHRpbWUgaGVhbHRoIGNoZWNrIChgL2hlYWx0aGAgb24gYSBgbW9kZTogcmVhbHRpbWVgIGRlcGxveW1lbnQsIGFuZCB0aGUgQWRtaW4gVUkncyBUZXN0IENvbm5lY3QpIGhhcyBubyBjbGllbnQgaGVhZGVyIHRvIHJlYWQsIHNvIGl0IHByb2JlcyB0aGUgR0EgZW5kcG9pbnQgdW5sZXNzIG9uZSBvZiB0aG9zZSBwaW5zIHRoZSBwcm90b2NvbAoKYGBgeWFtbAptb2RlbF9saXN0OgogIC0gbW9kZWxfbmFtZTogYXp1cmUtZ3B0LXJlYWx0aW1lCiAgICBsaXRlbGxtX3BhcmFtczoKICAgICAgbW9kZWw6IGF6dXJlL2dwdC1yZWFsdGltZQogICAgICBhcGlfa2V5OiBvcy5lbnZpcm9uL0FaVVJFX0FQSV9LRVkKICAgICAgYXBpX2Jhc2U6IG9zLmVudmlyb24vQVpVUkVfQVBJX0JBU0UKICAgICAgcmVhbHRpbWVfcHJvdG9jb2w6IGJldGEgIyBvciBHQQpgYGAKCmBgYGJhc2gKZXhwb3J0IExJVEVMTE1fQVpVUkVfUkVBTFRJTUVfUFJPVE9DT0w9YmV0YSAjIG9yIEdBCmBgYAoKIyMgR3VhcmRyYWlscwoKWW91IGNhbiBhcHBseSBbTGl0ZUxMTSBndWFyZHJhaWxzXShodHRwczovL2RvY3MubGl0ZWxsbS5haS9kb2NzL3Byb3h5L2d1YXJkcmFpbHMvcXVpY2tfc3RhcnQpIHRvIHJlYWx0aW1lIHNlc3Npb25zLgoKIyMjIFNldCBndWFyZHJhaWxzIG9uIGEga2V5IG9yIHRlYW0KClRoZSBlYXNpZXN0IHByb2R1Y3Rpb24gc2V0dXA6IGF0dGFjaCBndWFyZHJhaWxzIHRvIGEgdmlydHVhbCBrZXkgb3IgdGVhbSBzbyB0aGV5IGFsd2F5cyBhcHBseSBhdXRvbWF0aWNhbGx5LCB3aXRob3V0IGFueSBjbGllbnQtc2lkZSBjaGFuZ2VzLgoKU2VlIFtWaXJ0dWFsIEtleXMg4oaSIEd1YXJkcmFpbHNdKGh0dHBzOi8vZG9jcy5saXRlbGxtLmFpL2RvY3MvcHJveHkvdmlydHVhbF9rZXlzI2d1YXJkcmFpbHMpIGFuZCBbVGVhbXMg4oaSIEd1YXJkcmFpbHNdKGh0dHBzOi8vZG9jcy5saXRlbGxtLmFpL2RvY3MvcHJveHkvdGVhbV9idWRnZXRzKS4KCiMjIyBQYXNzIGd1YXJkcmFpbHMgZHluYW1pY2FsbHkgKGVhc3kgdGVzdGluZykKClBhc3MgYGd1YXJkcmFpbHNgIGFzIGEgcXVlcnkgcGFyYW0gd2hlbiBvcGVuaW5nIHRoZSBXZWJTb2NrZXQuClVzZWZ1bCBmb3IgdGVzdGluZyBndWFyZHJhaWxzIHdpdGhvdXQgbW9kaWZ5aW5nIGtleS90ZWFtIGNvbmZpZy4KCmBgYGpz
1Ci8vIG5vZGUgdGVzdC5qcwpjb25zdCBXZWJTb2NrZXQgPSByZXF1aXJlKCJ3cyIpOwoKY29uc3QgZ3VhcmRyYWlscyA9IFsieW91ci1ndWFyZHJhaWwtbmFtZSJdOyAvLyBjb21tYS1zZXBhcmF0ZWQgbGlzdApjb25zdCB1cmwgPSBgd3M6Ly8wLjAuMC4wOjQwMDAvdjEvcmVhbHRpbWU/bW9kZWw9b3BlbmFpLWdwdC00by1yZWFsdGltZS1hdWRpbyZndWFyZHJhaWxzPSR7Z3VhcmRyYWlscy5qb2luKCIsIil9YDsKCmNvbnN0IHdzID0gbmV3IFdlYlNvY2tldCh1cmwsIHsKICAgIGhlYWRlcnM6IHsKICAgICAgICAiQXV0aG9yaXphdGlvbiI6ICJCZWFyZXIgc2stPHlvdXItbGl0ZWxsbS1hcGkta2V5PiIsCiAgICB9LAp9KTsKCndzLm9uKCJvcGVuIiwgZnVuY3Rpb24gb3BlbigpIHsKICAgIGNvbnNvbGUubG9nKCJDb25uZWN0ZWQg4oCUIGd1YXJkcmFpbHMgYWN0aXZlOiIsIGd1YXJkcmFpbHMpOwp9KTsKCndzLm9uKCJtZXNzYWdlIiwgZnVuY3Rpb24gaW5jb21pbmcobWVzc2FnZSkgewogICAgY29uc3QgZGF0YSA9IEpTT04ucGFyc2UobWVzc2FnZSk7CiAgICBpZiAoZGF0YS50eXBlID09PSAiZXJyb3IiKSB7CiAgICAgICAgLy8gR3VhcmRyYWlsIGJsb2NrIGlzIHNlbnQgYXMgYW4gZXJyb3IgZXZlbnQgYmVmb3JlIHRoZSBjb25uZWN0aW9uIGNsb3NlcwogICAgICAgIGNvbnNvbGUuZXJyb3IoIkd1YXJkcmFpbCBlcnJvcjoiLCBkYXRhLmVycm9yLm1lc3NhZ2UpOwogICAgfQp9KTsKCndzLm9uKCJjbG9zZSIsIGZ1bmN0aW9uIGNsb3NlKGNvZGUsIHJlYXNvbikgewogICAgY29uc29sZS5sb2coIkNsb3NlZDoiLCBjb2RlLCByZWFzb24udG9TdHJpbmcoKSk7CiAgICAvLyBjb2RlIDEwMTEgPSBibG9ja2VkIGJ5IGd1YXJkcmFpbCBhdCBwcmVfY2FsbAp9KTsKYGBgCgpPciB3aXRoIFB5dGhvbjoKCmBgYHB5dGhvbgppbXBvcnQgYXN5bmNpbwppbXBvcnQgd2Vic29ja2V0cwoKYXN5bmMgZGVmIG1haW4oKToKICAgIHVybCA9ICJ3czovLzAuMC4wLjA6NDAwMC92MS9yZWFsdGltZT9tb2RlbD1vcGVuYWktZ3B0LTRvLXJlYWx0aW1lLWF1ZGlvJmd1YXJkcmFpbHM9eW91ci1ndWFyZHJhaWwtbmFtZSIKICAgIGFzeW5jIHdpdGggd2Vic29ja2V0cy5jb25uZWN0KAogICAgICAgIHVybCwKICAgICAgICBhZGRpdGlvbmFsX2hlYWRlcnM9eyJBdXRob3JpemF0aW9uIjogIkJlYXJlciBzay08eW91ci1saXRlbGxtLWFwaS1rZXk+In0sCiAgICApIGFzIHdzOgogICAgICAgIHByaW50KCJDb25uZWN0ZWQg4oCUIGd1YXJkcmFpbCBhY3RpdmUiKQogICAgICAgIGFzeW5jIGZvciBtc2cgaW4gd3M6CiAgICAgICAgICAgIGltcG9ydCBqc29uCiAgICAgICAgICAgIGRhdGEgPSBqc29uLmxvYWRzKG1zZykKICAgICAgICAgICAgaWYgZGF0YVsidHlwZSJdID09ICJlcnJvciI6CiAgICAgICAgICAgICAgICBwcmludCgiR3VhcmRyYWlsIGJsb2NrZWQ6IiwgZGF0YVsiZXJyb3IiXVsibWVzc2FnZSJdKQogICAgICAgICAgICAgICAgYnJlYWsKCmFzeW5jaW8ucnVuKG1haW4oKSkKYGBgCgpXaGVuIGEgZ3VhcmRyYWlsIGJsb2NrcyB0aGUgcmVxdWVzdCwgdGhlIHByb3h5IHNlbmRzIGFuIGBlcnJvcmAgZXZlbnQgb3ZlciB0aGUgV2ViU29ja2V0IGFuZCB0aGVuIGNsb3NlcyB0aGUgY29ubmVjdGlvbjoKCmBgYGpzb24KewogICAgInR5cGUiOiAiZXJyb3IiLAogICAgImVycm9yIjogewogICAgICAgICJ0eXBlIjogImd1YXJkcmFpbF9lcnJvciIsCiAgICAgICAgIm1lc3NhZ2UiOiAiR3VhcmRyYWlsIGJsb2NrZWQgdGhpcyByZXF1ZXN0OiA8cmVhc29uPiIKICAgIH0KfQpgYGAKCiMjIExvZ2dpbmcKClRvIHByZXZlbnQgcmVxdWVzdHMgZnJvbSBiZWluZyBkcm9wcGVkLCBieSBkZWZhdWx0IExpdGVMTE0ganVzdCBsb2dzIHRoZXNlIGV2ZW50IHR5cGVzOgoKLSBgc2Vzc2lvbi5jcmVhdGVkYAotIGByZXNwb25zZS5jcmVhdGVgCi0gYHJlc3BvbnNlLmRvbmVgCgpZb3UgY2FuIG92ZXJyaWRlIHRoaXMgYnkgc2V0dGluZyB0aGUgYGxvZ2dlZF9yZWFsX3RpbWVfZXZlbnRfdHlwZXNgIHBhcmFtZXRlciBpbiB0aGUgY29uZmlnLiBGb3IgZXhhbXBsZToKCmBgYHlhbWwKbGl0ZWxsbV9zZXR0aW5nczoKICBsb2dnZWRfcmVhbF90aW1lX2V2ZW50X3R5cGVzOiAiKiIgIyBMb2cgYWxsIGV2ZW50cwogICMjIE9SICMjIAogIGxvZ2dlZF9yZWFsX3RpbWVfZXZlbnRfdHlwZXM6IFsic2Vzc2lvbi5jcmVhdGVkIiwgInJlc3BvbnNlLmNyZWF0ZSIsICJyZXNwb25zZS5kb25lIl0gIyBMb2cgb25seSB0aGVzZSBldmVudCB0eXBlcwpgYGAK"},c="/realtime",d={},g=[{value:"Proxy Usage",id:"proxy-usage",level:2},{value:"Add model to config",id:"add-model-to-config",level:3},{value:"Start proxy",id:"start-proxy",level:3},{value:"Test",id:"test",level:3},{value:"Azure: GA vs beta realtime protocol",id:"azure-ga-vs-beta-realtime-protocol",level:2},{value:"Guardrails",id:"guardrails",level:2},{value:"Set guardrails on a key or team",id:"set-guardrails-on-a-key-or-team",level:3},{value:"Pass guardrails dynamically (easy testing)",id:"pass-guardrails-dynamically-easy-testing",level:3},{value:"Logging",id:"logging",level:2}];function I(e){let n={a:"a",code:"code",h1:"h1",h2:"h2",h3:"h3",header:"header",li:"li",p:"p",pre:"pre",strong:"strong",ul:"ul",...(0,s.R)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(n.header,{children:(0,i.jsx)(n.h1,{id:"realtime",children:"/realtime"})}),"\n",(0,i.jsx)(n.p,{children:"Use this to loadbalance across Azure + OpenAI + xAI and more."}),"\n",(0,i.jsx)(n.p,{children:"Supported Providers:"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:"OpenAI"}),"\n",(0,i.jsx)(n.li,{children:"Azure"}),"\n",(0,i.jsxs)(n.li,{children:["xAI (",(0,i.jsx)(n.a,{href:"/docs/providers/xai_realtime",children:"see full docs"}),")"]}),"\n",(0,i.jsx)(n.li,{children:"Google AI Studio (Gemini)"}),"\n",(0,i.jsx)(n.li,{children:"Vertex AI"}),"\n",(0,i.jsxs)(n.li,{children:["Vertex AI Chirp, transcription only (",(0,i.jsx)(n.a,{href:"/docs/providers/vertex_transcription#chirp-realtime-transcription",children:"see full docs"}),")"]}),"\n",(0,i.jsx)(n.li,{children:"Bedrock"}),"\n",(0,i.jsxs)(n.li,{children:["Meta Muse Voice, transcription only (",(0,i.jsx)(n.a,{href:"/docs/providers/meta#muse-voice-realtime-transcription",children:"see full docs"}),")"]}),"\n"]}),"\n",(0,i.jsx)(n.h2,{id:"proxy-usage",children:"Proxy Usage"}),"\n",(0,i.jsx)(n.h3,{id:"add-model-to-config",children:"Add model to config"}),"\n",(0,i.jsxs)(t.A,{children:[(0,i.jsx)(r.A,{value:"openai",label:"OpenAI",children:(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-yaml",children:"model_list:\n  - model_name: openai-gpt-4o-realtime-audio\n    litellm_params:\n      model: openai/gpt-4o-realtime-preview-2024-10-01\n      api_key: os.environ/OPENAI_API_KEY\n    model_info:\n      mode: realtime\n"})})}),(0,i.jsx)(r.A,{value:"openai+azure",label:"OpenAI + Azure",children:(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-yaml",children:"model_list:\n  - model_name: azure-gpt-4o-realtime-audio\n    litellm_params:\n      model: azure/gpt-4o-realtime-preview\n      api_key: os.environ/AZURE_SWEDEN_API_KEY\n      api_base
1: os.environ/AZURE_SWEDEN_API_BASE\n\n  - model_name: azure-gpt-realtime\n    litellm_params:\n      model: azure/gpt-realtime\n      api_key: os.environ/AZURE_API_KEY\n      api_base: os.environ/AZURE_API_BASE\n    model_info:\n      mode: realtime\n\n  - model_name: openai-gpt-4o-realtime-audio\n    litellm_params:\n      model: openai/gpt-4o-realtime-preview-2024-10-01\n      api_key: os.environ/OPENAI_API_KEY\n"})})}),(0,i.jsxs)(r.A,{value:"xai",label:"xAI Grok Voice Agent",children:[(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-yaml",children:"model_list:\n  - model_name: grok-voice-agent\n    litellm_params:\n      model: xai/grok-voice-latest\n      api_key: os.environ/XAI_API_KEY\n    model_info:\n      mode: realtime\n"})}),(0,i.jsx)(n.p,{children:(0,i.jsx)(n.strong,{children:(0,i.jsx)(n.a,{href:"/docs/providers/xai_realtime",children:"See full xAI Realtime documentation \u2192"})})})]})]}),"\n",(0,i.jsx)(n.h3,{id:"start-proxy",children:"Start proxy"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"litellm --config /path/to/config.yaml \n\n# RUNNING on http://0.0.0.0:4000\n"})}),"\n",(0,i.jsx)(n.h3,{id:"test",children:"Test"}),"\n",(0,i.jsxs)(n.p,{children:["Run this script using node - ",(0,i.jsx)(n.code,{children:"node test.js"})]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-js",children:'// test.js\nconst WebSocket = require("ws");\n\nconst url = "ws://0.0.0.0:4000/v1/realtime?model=openai-gpt-4o-realtime-audio";\n// const url = "wss://my-azure-endpoint.openai.azure.com/openai/realtime?api-version=2024-10-01-preview&deployment=gpt-4o-realtime-preview";\nconst ws = new WebSocket(url, {\n    headers: {\n        "api-key": `sk-<your-litellm-api-key>`,\n        "OpenAI-Beta": "realtime=v1",\n    },\n});\n\nws.on("open", function open() {\n    console.log("Connected to server.");\n    ws.send(JSON.stringify({\n        type: "response.create",\n        response: {\n            modalities: ["text"],\n            instructions: "Please assist the user.",\n        }\n    }));\n});\n\nws.on("message", function incoming(message) {\n    console.log(JSON.parse(message.toString()));\n});\n\nws.on("error", function handleError(error) {\n    console.error("Error: ", error);\n});\n'})}),"\n",(0,i.jsx)(n.h2,{id:"azure-ga-vs-beta-realtime-protocol",children:"Azure: GA vs beta realtime protocol"}),"\n",(0,i.jsxs)(n.p,{children:["Azure exposes two realtime upstreams. The GA endpoint (",(0,i.jsx)(n.code,{children:"/openai/v1/realtime?model=<deployment>"}),") speaks the GA event schema (",(0,i.jsx)(n.code,{children:"session.type"}),", ",(0,i.jsx)(n.code,{children:"output_modalities"}),", nested ",(0,i.jsx)(n.code,{children:"audio"}),"), and the older beta endpoint (",(0,i.jsx)(n.code,{children:"/openai/realtime?api-version=2024-10-01-preview&deployment=<deployment>"}),") speaks the beta schema (",(0,i.jsx)(n.code,{children:"modalities"}),", ",(0,i.jsx)(n.code,{children:"voice"}),", flat audio formats). Sending a GA-shaped ",(0,i.jsx)(n.code,{children:"session.update"})," to the beta endpoint fails with ",(0,i.jsx)(n.code,{children:"Unknown parameter: 'session.type'"})]}),"\n",(0,i.jsxs)(n.p,{children:["LiteLLM picks the upstream from the client connection. A client that sends the ",(0,i.jsx)(n.code,{children:"OpenAI-Beta: realtime=v1"})," header (the openai SDK's ",(0,i.jsx)(n.code,{children:"client.beta.realtime.connect"}),") is bridged to the beta endpoint. A client without that header (the openai SDK's ",(0,i.jsx)(n.code,{children:"client.realtime.connect"}),", and most voice agent frameworks) is bridged to the GA endpoint. Transcription sessions (",(0,i.jsx)(n.code,{children:"intent=transcription"}),") always use GA"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-python",children:'from openai import AsyncOpenAI\n\nclient = AsyncOpenAI(base_url="http://0.0.0.0:4000", api_key="sk-1234")\n\nasync with client.realtime.connect(model="azure-gpt-realtime") as connection:\n    await connection.session.update(\n        session={"type": "realtime", "output_modalities": ["audio"], "instructions": "Please assist the user."}\n    )\n    async for event in connection:\n        print(event.type)\n        if event.type == "session.updated":\n            break\n'})}),"\n",(0,i.jsxs)(n.p,{children:["To pin one protocol regardless of what the client sends, set ",(0,i.jsx)(n.code,{children:"realtime_protocol"})," on the deployment or ",(0,i.jsx)(n.code,{children:"LITELLM_AZURE_REALTIME_PROTOCOL"})," in the proxy's environment. The deployment setting wins over the environment variable, and both win over the client header. The realtime health check (",(0,i.jsx)(n.code,{children:"/health"})," on a ",(0,i.jsx)(n.code,{children:"mode: realtime"})," deployment, and the Admin UI's Test Connect) has no client header to read, so it probes the GA endpoint unless one of those pins the protocol"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-yaml",children:"model_list:\n  - model_name: azure-gpt-realtime\n    litellm_params:\n      model: azure/gpt-realtime\n      api_key: os.environ/AZURE_API_KEY\n      api_base
1: os.environ/AZURE_API_BASE\n      realtime_protocol: beta # or GA\n"})}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"export LITELLM_AZURE_REALTIME_PROTOCOL=beta # or GA\n"})}),"\n",(0,i.jsx)(n.h2,{id:"guardrails",children:"Guardrails"}),"\n",(0,i.jsxs)(n.p,{children:["You can apply ",(0,i.jsx)(n.a,{href:"https://docs.litellm.ai/docs/proxy/guardrails/quick_start",children:"LiteLLM guardrails"})," to realtime sessions."]}),"\n",(0,i.jsx)(n.h3,{id:"set-guardrails-on-a-key-or-team",children:"Set guardrails on a key or team"}),"\n",(0,i.jsx)(n.p,{children:"The easiest production setup: attach guardrails to a virtual key or team so they always apply automatically, without any client-side changes."}),"\n",(0,i.jsxs)(n.p,{children:["See ",(0,i.jsx)(n.a,{href:"https://docs.litellm.ai/docs/proxy/virtual_keys#guardrails",children:"Virtual Keys \u2192 Guardrails"})," and ",(0,i.jsx)(n.a,{href:"https://docs.litellm.ai/docs/proxy/team_budgets",children:"Teams \u2192 Guardrails"}),"."]}),"\n",(0,i.jsx)(n.h3,{id:"pass-guardrails-dynamically-easy-testing",children:"Pass guardrails dynamically (easy testing)"}),"\n",(0,i.jsxs)(n.p,{children:["Pass ",(0,i.jsx)(n.code,{children:"guardrails"})," as a query param when opening the WebSocket.\nUseful for testing guardrails without modifying key/team config."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-js",children:'// node test.js\nconst WebSocket = require("ws");\n\nconst guardrails = ["your-guardrail-name"]; // comma-separated list\nconst url = `ws://0.0.0.0:4000/v1/realtime?model=openai-gpt-4o-realtime-audio&guardrails=${guardrails.join(",")}`;\n\nconst ws = new WebSocket(url, {\n    headers: {\n        "Authorization": "Bearer sk-<your-litellm-api-key>",\n    },\n});\n\nws.on("open", function open() {\n    console.log("Connected \u2014 guardrails active:", guardrails);\n});\n\nws.on("message", function incoming(message) {\n    const data = JSON.parse(message);\n    if (data.type === "error") {\n        // Guardrail block is sent as an error event before the connection closes\n        console.error("Guardrail error:", data.error.message);\n    }\n});\n\nws.on("close", function close(code, reason) {\n    console.log("Closed:", code, reason.toString());\n    // code 1011 = blocked by guardrail at pre_call\n});\n'})}),"\n",(0,i.jsx)(n.p,{children:"Or with Python:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-python",children:'import asyncio\nimport websockets\n\nasync def main():\n    url = "ws://0.0.0.0:4000/v1/realtime?model=openai-gpt-4o-realtime-audio&guardrails=your-guardrail-name"\n    async with websockets.connect(\n        url,\n        additional_headers={"Authorization": "Bearer sk-<your-litellm-api-key>"},\n    ) as ws:\n        print("Connected \u2014 guardrail active")\n        async for msg in ws:\n            import json\n            data = json.loads(msg)\n            if data["type"] == "error":\n                print("Guardrail blocked:", data["error"]["message"])\n                break\n\nasyncio.run(main())\n'})}),"\n",(0,i.jsxs)(n.p,{children:["When a guardrail blocks the request, the proxy sends an ",(0,i.jsx)(n.code,{children:"error"})," event over the WebSocket and then closes the connection:"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-json",children:'{\n    "type": "error",\n    "error": {\n        "type": "guardrail_error",\n        "message": "Guardrail blocked this request: <reason>"\n    }\n}\n'})}),"\n",(0,i.jsx)(n.h2,{id:"logging",children:"Logging"}),"\n",(0,i.jsx)(n.p,{children:"To prevent requests from being dropped, by default LiteLLM just logs these event types:"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:(0,i.jsx)(n.code,{children:"session.created"})}),"\n",(0,i.jsx)(n.li,{children:(0,i.jsx)(n.code,{children:"response.create"})}),"\n",(0,i.jsx)(n.li,{children:(0,i.jsx)(n.code,{children:"response.done"})}),"\n"]}),"\n",(0,i.jsxs)(n.p,{children:["You can override this by setting the ",(0,i.jsx)(n.code,{children:"logged_real_time_event_types"})," parameter in the config. For example:"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-yaml",children:'litellm_settings:\n  logged_real_time_event_types: "*" # Log all events\n  ## OR ## \n  logged_real_time_event_types: ["session.created", "response.create", "response.done"] # Log only these event types\n'})})]})}function b(e={}){let{wrapper:n}={...(0,s.R)(),...e.components};return n?(0,i.jsx)(n,{...e,children:(0,i.jsx)(I,{...e})}):I(e)}},5400(e,n,l){l.d(n,{A:()=>s});var a=l(74848);l(96540);var i=l(34164);function s({children:e,hidden:n,className:l}){return(0,a.jsx)("div",{role:"tabpanel",className:(0,i.A)("tabItem_Ymn6",l),hidden:n,children:e})}},53720(e,n,l){l.d(n,{A:()=>G});var a=l(74848),i=l(96540),s=l(34164),t=l(65697),r=l(56347),o=l(56650),c=l(9226),d=l(34387),g=l(10426);function I(e){return i.Children.toArray(e).filter(e=>"\n"!==e).map(e=>{if(!e||(0,i.isValidElement)(e)&&function(e){let{props:n}=e;return!!n&&"object"==typeof n&&"value"in n}(e))return e;throw Error(`Docusaurus error: Bad <Tabs>
1 child <${"string"==typeof e.type?e.type:e.type.name}>: all children of the <Tabs> component should be <TabItem>, and every <TabItem> should have a unique "value" prop.`)})?.filter(Boolean)??[]}function b({value:e,tabValues:n}){return n.some(n=>n.value===e)}var m=l(20162);function u({className:e,block:n,selectedValue:l,selectValue:i,tabValues:r}){let o=[],{blockElementScrollPositionUntilNextRender:c}=(0,t.a_)(),d=e=>{let n=e.currentTarget,a=r[o.indexOf(n)].value;a!==l&&(c(n),i(a))},g=e=>{let n=null;switch(e.key){case"Enter":d(e);break;case"ArrowRight":{let l=o.indexOf(e.currentTarget)+1;n=o[l]??o[0];break}case"ArrowLeft":{let l=o.indexOf(e.currentTarget)-1;n=o[l]??o[o.length-1]}}n?.focus()};return(0,a.jsx)("ul",{role:"tablist","aria-orientation":"horizontal",className:(0,s.A)("tabs",{"tabs--block":n},e),children:r.map(({value:e,label:n,attributes:i})=>(0,a.jsx)("li",{role:"tab",tabIndex:l===e?0:-1,"aria-selected":l===e,ref:e=>{o.push(e)},onKeyDown:g,onClick:d,...i,className:(0,s.A)("tabs__item","tabItem_LNqP",i?.className,{"tabs__item--active":l===e}),children:n??e},e))})}function p({lazy:e,children:n,selectedValue:l}){let t=(Array.isArray(n)?n:[n]).filter(Boolean);if(e){let e=t.find(e=>e.props.value===l);return e?(0,i.cloneElement)(e,{className:(0,s.A)("margin-top--md",e.props.className)}):null}return(0,a.jsx)("div",{className:"margin-top--md",children:t.map((e,n)=>(0,i.cloneElement)(e,{key:n,hidden:e.props.value!==l}))})}function h(e){let n=function(e){let n,{defaultValue:l,queryString:a=!1,groupId:s}=e,t=function(e){let{values:n,children:l}=e;return(0,i.useMemo)(()=>{let e=n??I(l).map(({props:{value:e,label:n,attributes:l,default:a}})=>({value:e,label:n,attributes:l,default:a})),a=(0,d.XI)(e,(e,n)=>e.value===n.value);if(a.length>0)throw Error(`Docusaurus error: Duplicate values "${a.map(e=>e.value).join(", ")}" found in <Tabs>. Every value needs to be unique.`);return e},[n,l])}(e),[m,u]=(0,i.useState)(()=>(function({defaultValue:e,tabValues:n}){if(0===n.length)throw Error("Docusaurus error: the <Tabs> component requires at least one <TabItem> children component");if(e){if(!b({value:e,tabValues:n}))throw Error(`Docusaurus error: The <Tabs> has a defaultValue "${e}" but none of its children has the corresponding value. Available values are: ${n.map(e=>e.value).join(", ")}. If you intend to show no default tab, use defaultValue={null} instead.`);return e}let l=n.find(e=>e.default)??n[0];if(!l)throw Error("Unexpected error: 0 tabValues");return l.value})({defaultValue:l,tabValues:t})),[p,h]=function({queryString:e=!1,groupId:n}){let l=(0,r.W6)(),a=function({queryString:e=!1,groupId:n}){if("string"==typeof e)return e;if(!1===e)return null;if(!0===e&&!n)throw Error('Docusaurus error: The <Tabs> component groupId prop is required if queryString=true, because this value is used as the search param name. You can also provide an explicit value such as queryString="my-search-param".');return n??null}({queryString:e,groupId:n});return[(0,c.aZ)(a),(0,i.useCallback)(e=>{if(!a)return;let n=new URLSearchParams(l.location.search);n.set(a,e),l.replace({...l.location,search:n.toString()})},[a,l])]}({queryString:a,groupId:s}),[G,Z]=function({groupId:e}){let n=e?`docusaurus.tab.${e}`:null,[l,a]=(0,g.Dv)(n);return[l,(0,i.useCallback)(e=>{n&&a.set(e)},[n,a])]}({groupId:s}),C=b({value:n=p??G,tabValues:t})?n:null;return(0,o.A)(()=>{C&&u(C)},[C]),{selectedValue:m,selectValue:(0,i.useCallback)(e=>{if(!b({value:e,tabValues:t}))throw Error(`Can't select invalid tab value=${e}`);u(e),h(e),Z(e)},[h,Z,t]),tabValues:t}}(e);return(0,a.jsxs)("div",{className:(0,s.A)("tabs-container","tabList__CuJ"),children:[(0,a.jsx)(u,{...n,...e}),(0,a.jsx)(p,{...n,...e})]})}function G(e){let n=(0,m.A)();return(0,a.jsx)(h,{...e,children:I(e.children)},String(n))}},28453(e,n,l){l.d(n,{R:()=>t,x:()=>r});var a=l(96540);let i={},s=a.createContext(i);function t(e){let n=a.useContext(s);return a.useMemo(function(){return"function"==typeof e?e(n):{...n,...e}},[n,e])}function r(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:t(e.components),a.createElement(s.Provider,{value:n},e.children)}}}]);

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.