Read one partner model's catalog entry by canonical model ID.
Per-model detail for a single Comfy Router model, so a caller can check one model without walking the whole paginated catalog. The SDKs use it to look a model up immediately before invoking it.
GET
/
v2
/
models
/
{provider}
/
{model}
Read one partner model's catalog entry by canonical model ID.
Bearer token authentication. Normally a Firebase or Cloud JWT. A 'comfyui-' prefixed API key is also accepted in this header: the prefix classifies the value as an API key and it is validated exactly as if it had been sent in X-API-Key.
The ETag a caller holds from an earlier 200. When it matches the current entry (RFC 9110 weak comparison; * matches any current entry) the answer is a bodyless 304 carrying the same ETag, otherwise the full entry.
Lowercase provider segment of the canonical {provider}/{model} model ID - the partner whose model is being run.
Lowercase provider segment of the canonical {provider}/{model} model ID - the partner whose model is being addressed. The invocation route's provider path parameter and a catalog entry's provider field both reference this one schema, which is what keeps the listed IDs and the accepted IDs from drifting apart.
Lowercase model segment of the canonical {provider}/{model} model ID - the model to run within that provider.
Lowercase model segment of the canonical {provider}/{model} model ID - the model to run within that provider. Shared by the invocation route's model path parameter and a catalog entry's model field, for the same no-drift reason as RouterProviderSegment.
Maximum string length: 128
Pattern: ^[a-z0-9]+([._-][a-z0-9]+)*$
예시:
"flux-2-pro"
응답
OK - the model's catalog entry.
Per-model detail for one Comfy Router model: everything the catalog listing reports for it, plus the per-model fields that only the single-model route carries.
A canonical Comfy Router model ID, {provider}/{model} - exactly the value that addresses the model on POST /v2/models/{provider}/{model}, so a caller can interpolate it into that path without re-deriving it from anything. Its pattern is RouterProviderSegment and RouterModelSegment joined by a single /, and maxLength is their sum plus that separator.
Lowercase provider segment of the canonical {provider}/{model} model ID - the partner whose model is being addressed. The invocation route's provider path parameter and a catalog entry's provider field both reference this one schema, which is what keeps the listed IDs and the accepted IDs from drifting apart.
Lowercase model segment of the canonical {provider}/{model} model ID - the model to run within that provider. Shared by the invocation route's model path parameter and a catalog entry's model field, for the same no-drift reason as RouterProviderSegment.
The current strong ETag of this model's GET /v2/models/{provider}/{model}/openapi.json document. Send it as If-None-Match on that read to get a 304 while the schema is unchanged, or compare it with the value seen last time to learn which models' schemas changed without fetching every document. Absent whenever that read would not answer 200 for this caller at this moment: the schema service is not available, the model's document cannot be rendered, or the model stopped being available to this caller while the response was being built. An absent tag is not a schema change; re-read the model's document to learn its current tag.
Pointer to this model's input schema document - the description of the body POST /v2/models/{provider}/{model} accepts for this model. Only the pointer is part of this contract: the document it addresses is authored separately. Absent when no schema has been authored for the model.
{"docsConfig":{"theme":"mint","$schema":"https://mintlify.com/docs.json","name":"ComfyUI","colors":{"primary":"#49378B","light":"#F2FF59","dark":"#F2FF59"},"logo":{"light":"https://mintcdn.com/dripart/WCFdTagRdhtvk9-o/logo/light.svg?fit=max\u0026auto=format\u0026n=WCFdTagRdhtvk9-o\u0026q=85\u0026s=ec112de87239058f5a931a7e4b594965","dark":"https://mintcdn.com/dripart/QzWbjSCBG7w61rR3/logo/dark.svg?fit=max\u0026auto=format\u0026n=QzWbjSCBG7w61rR3\u0026q=85\u0026s=62b4d879fb3aadbd7a468d1539032d6f","href":"/"},"favicon":"https://mintcdn.com/dripart/maKDA164-rrTfyxY/favicon.ico?fit=max\u0026auto=format\u0026n=maKDA164-rrTfyxY\u0026q=85\u0026s=94f3a697cf4c9a1ee3961b69219d0942","appearance":{"default":"dark"},"navbar":{"links":[{"href":"https://blog.comfy.org/?utm_source=docs","label":"Blog"},{"href":"/tutorials/partner-nodes/pricing","label":"Pricing"},{"href":"https://platform.comfy.org/?utm_source=docs","label":"Platform"},{"href":"https://comfy.org/download?utm_source=docs","label":"Download"}],"primary":{"type":"button","label":"Comfy Cloud","href":"https://comfy.org/cloud?utm_source=docs"}},"footer":{"socials":{"github":"https://github.com/Comfy-Org/ComfyUI","x":"https://x.com/ComfyUI","discord":"https://discord.com/invite/comfyorg","youtube":"https://www.youtube.com/@comfyorg"},"links":[{"header":"Resources","items":[{"label":"installation","href":"/installation/system_requirements"},{"label":"Tutorials","href":"/tutorials/basic/text-to-image"},{"label":"Development","href":"/development/overview"}]},{"header":"Products","items":[{"label":"Features","href":"https://www.comfy.org/?utm_source=docs"},{"label":"Gallery","href":"https://www.comfy.org/gallery?utm_source=docs"},{"label":"Download","href":"https://www.comfy.org/download?utm_source=docs"}]},{"header":"Company","items":[{"label":"About","href":"https://www.comfy.org/about?utm_source=docs"},{"label":"Careers","href":"https://www.comfy.org/careers?utm_source=docs"},{"label":"Terms of Service","href":"https://www.comfy.org/terms-of-service?utm_source=docs"},{"label":"Privacy Policy","href":"https://www.comfy.org/privacy-policy?utm_source=docs"}]}]},"search":{"prompt":"Search Comfy documentation..."},"seo":{"metatags":{"googlebot":"max-video-preview:0"}},"icons":{"library":"fontawesome"},"integrations":{"ga4":{"measurementId":"G-MXC01ZDDHQ"},"posthog":{"apiKey":"phc_iKfK86id4xVYws9LybMje0h44eGtfwFgRPIBehmy8rO"}},"contextual":{"options":["copy","view","chatgpt","claude"],"display":"header"},"styling":{"latex":true},"navigation":{"languages":[{"language":"en","href":""},{"language":"zh","footer":{"socials":{"github":"https://github.com/Comfy-Org/ComfyUI","x":"https://x.com/ComfyUI","discord":"https://discord.com/invite/comfyorg","youtube":"https://www.youtube.com/@comfyorg"},"links":[{"header":"资源","items":[{"label":"安装","href":"/zh/installation/system_requirements"},{"label":"教程","href":"/zh/tutorials/basic/text-to-image"},{"label":"开发","href":"/zh/development/overview"}]},{"header":"产品","items":[{"label":"功能","href":"https://www.comfy.org/?utm_source=docs"},{"label":"画廊","href":"https://www.comfy.org/gallery?utm_source=docs"},{"label":"下载","href":"https://www.comfy.org/download?utm_source=docs"}]},{"header":"公司","items":[{"label":"关于","href":"https://www.comfy.org/about?utm_source=docs"},{"label":"招聘","href":"https://www.comfy.org/careers?utm_source=docs"},{"label":"服务条款","href":"https://www.comfy.org/terms-of-service?utm_source=docs"},{"label":"隐私政策","href":"https://www.comfy.org/privacy-policy?utm_source=docs"}]}]},"href":"zh"},{"language":"ja","footer":{"socials":{"github":"https://github.com/Comfy-Org/ComfyUI","x":"https://x.com/ComfyUI","discord":"https://discord.com/invite/comfyorg","youtube":"https://www.youtube.com/@comfyorg"},"links":[{"header":"リソース","items":[{"label":"インストール","href":"/ja/installation/system_requirements"},{"label":"チュートリアル","href":"/ja/tutorials/basic/text-to-image"},{"label":"開発","href":"/ja/development/overview"}]},{"header":"プロダクト","items":[{"label":"機能","href":"https://www.comfy.org/?utm_source=docs"},{"label":"ギャラリー","href":"https://www.comfy.org/gallery?utm_source=docs"},{"label":"ダウンロード","href":"https://www.comfy.org/download?utm_source=docs"}]},{"header":"会社情報","items":[{"label":"概要","href":"https://www.comfy.org/about?utm_source=docs"},{"label":"採用情報","href":"https://www.comfy.org/careers?utm_source=docs"},{"label":"利用規約","href":"https://www.comfy.org/terms-of-service?utm_source=docs"},{"label":"プライバシーポリシー","href":"https://www.comfy.org/privacy-policy?utm_source=docs"}]}]},"navbar":{"links":[{"href":"/ja/tutorials/partner-nodes/pricing","label":"料金"},{"href":"https://comfy.org/download?utm_source=docs","label":"ダウンロード"}],"primary":{"type":"button","label":"Comfy Cloud","href":"https://comfy.org/cloud?utm_source=docs"}},"href":"ja"},{"language":"ko","footer":{"socials":{"github":"https://github.com/Comfy-Org/ComfyUI","x":"https://x.com/ComfyUI","discord":"https://discord.com/invite/comfyorg","youtube":"https://www.youtube.com/@comfyorg"},"links":[{"header":"리소스","items":[{"label":"설치","href":"/ko/installation/system_requirements"},{"label":"튜토리얼","href":"/ko/tutorials/basic/text-to-image"},{"label":"개발","href":"/ko/development/overview"}]},{"header":"제품","items":[{"label":"기능","href":"https://www.comfy.org/?utm_source=docs"},{"label":"갤러리","href":"https://www.comfy.org/gallery?utm_source=docs"},{"label":"다운로드","href":"https://www.comfy.org/download?utm_source=docs"}]},{"header":"회사 정보","items":[{"label":"소개","href":"https://www.comfy.org/about?utm_source=docs"},{"label":"채용","href":"https://www.comfy.org/careers?utm_source=docs"},{"label":"이용약관","href":"https://www.comfy.org/terms-of-service?utm_source=docs"},{"label":"개인정보 처리방침","href":"https://www.comfy.org/privacy-policy?utm_source=docs"}]}]},"navbar":{"links":[{"href":"/ko/tutorials/partner-nodes/pricing","label":"가격 정책"},{"href":"https://comfy.org/download?utm_source=docs","label":"다운로드"}],"primary":{"type":"button","label":"Comfy Cloud","href":"https://comfy.org/cloud?utm_source=docs"}},"href":"ko"},{"language":"es","href":"es"}]}},"deployment":{"deploymentMetadataValue":{"subdomain":"dripart","hasAudioNarration":false,"actualSubdomain":"dripart","customDomains":["docs.comfy.org"],"gitSource":{"type":"github","owner":"comfy-org","repo":"docs","deployBranch":"main","contentDirectory":"","isPrivate":false,"mountPath":"","label":""},"feedback":{"thumbs":true,"edits":true,"issues":true,"agentFeedback":true},"entitlements":{"AI_CHAT":{"status":"DISABLED"},"WEB_MCP":{"status":"ENABLED"},"NARRATION":{"status":"DISABLED"}},"buildId":"6af261920e545c261afe8f45","clientVersion":"0.0.4094","searchFilterCounts":[{"language":"en","tag":"Built-in Nodes","count":1166},{"language":"ja","tag":"組み込みノード","count":1166},{"language":"zh","tag":"内置节点","count":1166},{"language":"en","tag":"Nodes","count":1165},{"language":"ja","tag":"ノード","count":1165},{"language":"zh","tag":"节点","count":1165},{"language":"ko","tag":"내장 노드 (Built-in Nodes)","count":1124},{"language":"ko","tag":"노드","count":1123},{"language":"es","tag":"Nodos integrados","count":1058},{"language":"es","tag":"Nodos","count":1057},{"language":"en","tag":"Tutorials","count":419},{"language":"es","tag":"Tutoriales","count":419},{"language":"en","tag":"Model","count":381},{"language":"ja","tag":"Model","count":381},{"language":"ko","tag":"Model","count":381},{"language":"zh","tag":"Model","count":381},{"language":"es","tag":"Modelo","count":378},{"language":"en","tag":"Image","count":355},{"language":"en","tag":"Partner","count":348},{"language":"ja","tag":"Partner","count":348},{"language":"ko","tag":"Partner","count":348},{"language":"zh","tag":"Partner","count":348},{"language":"es","tag":"Partner","count":346},{"language":"ja","tag":"API 開発","count":326},{"language":"ko","tag":"API 개발","count":326},{"language":"zh","tag":"API 开发","count":326},{"language":"es","tag":"Imagen","count":325},{"language":"ja","tag":"はじめに","count":312},{"language":"ko","tag":"시작하기","count":312},{"language":"zh","tag":"开始使用","count":312},{"language":"en","tag":"Video","count":291},{"language":"en","tag":"Comfy Router","count":289},{"language":"ja","tag":"Comfy Router","count":289},{"language":"ko","tag":"Comfy Router","count":289},{"language":"zh","tag":"Comfy Router","count":289},{"language":"es","tag":"Video","count":266},{"language":"es","tag":"Comfy Router","count":266},{"language":"en","tag":"Models","count":259},{"language":"ja","tag":"Models","count":259},{"language":"ko","tag":"Models","count":259},{"language":"zh","tag":"Models","count":259},{"language":"en","tag":"All Models","count":256},{"language":"es","tag":"Models","count":227},{"language":"es","tag":"All Models","count":224},{"language":"ja","tag":"画像","count":207},{"language":"ko","tag":"이미지","count":207},{"language":"zh","tag":"图像","count":207},{"language":"ja","tag":"Video","count":193},{"language":"zh","tag":"Video","count":193},{"language":"ko","tag":"Video","count":176}],"searchSettings":{"maxResults":10}},"assistantConfig":{"enableStarterQuestions":false},"basePath":"","hasChatPermissions":false,"hasWebMcpPermissions":true,"toggles":[{"name":"kill-isr","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"custom-rbac-roles","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"agent-mintlify-slack","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"agent-integrations-settings","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"rbac-expansion","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"automations-pr-grouping","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"custom-prefix","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"analytics-v7","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"user-flows-analytics","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"no-publish-flow","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"workos-onboarding","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"llms-txt-v2","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"snapshot-serving-live","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"stripTemperatureMiddleware","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"support-platform-pylon-zendesk","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"snapshot-serving","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"instant-rollback","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"granular-notifications-server","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"granular-notifications","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"automations-fable","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"fixed-ai-action-pricing","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"automation-resolve-merge-conflict","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"scoped-publishing","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"mintql","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"page-level-analytics","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"editor-version-history-v2","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"billing-page-v2","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"full-page-search","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"workspace-projects","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"assistant-v5","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"fork-pr-previews","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"revalidation-jwt","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"workos-sso-scim","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"hobby-abuse-scan","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"dashboard-inbox","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"workos-signup","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"turbopuffer-dual-write","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"workos-enabled","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"approve-review-flow","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"editor-metadata","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"sso-setup-deadline-banner","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"turbopuffer-serve","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"live-agents","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"comment-mode","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false}],"googleFontsInlined":false},"customCss":[{"filePath":"custom.css","content":":root{--ink-900: #151417;--hub-shell-light: #f7f6f9;--accent-purple: #49378b;--accent-yellow: #f2ff59;--primary: 73 55 139 !important;--primary-light: 242 255 89 !important;--primary-dark: 242 255 89 !important}html.dark{--primary: 242 255 89 !important;--background-dark: 14 14 13 !important}html.dark body{background-color:#0e0e0d!important}html.dark #navbar,html.dark #navbar-transition{background-color:var(--ink-900)!important}html.dark #sidebar,html.dark #sidebar-content{background-color:rgb(var(--background-dark))!important}html.dark #navbar,html.dark #navbar-transition{box-shadow:none!important;filter:none!important;backdrop-filter:none!important;-webkit-backdrop-filter:none!important}html.dark #navbar-transition{border-bottom:1px solid rgba(255, 255, 255, 0.08)!important;opacity:1!important}html.dark img.nav-logo{filter:none}html.dark #sidebar-content a:not([aria-current=\"page\"]){color:rgba(255, 255, 255, 0.72)!important}html.dark #sidebar-content a:not([aria-current=\"page\"]) *{color:inherit!important}html.dark #sidebar-content a[aria-current=\"page\"]{color:var(--accent-yellow)!important;background-color:rgba(242, 255, 89, 0.10)!important}html.dark #sidebar-content a[aria-current=\"page\"] *{color:inherit!important}html.dark .nav-tabs-item[data-active],html.dark mobile-nav-tabs-item[data-active]{color:var(--accent-yellow)!important}html.dark #navbar a[href*=\"comfy.org/cloud\"] span.absolute{background-color:var(--accent-yellow)!important}html.dark #navbar a[href*=\"comfy.org/cloud\"] span.text-white{color:#151417!important}html:not(.dark) #background-color,html:not(.dark) #navbar,html:not(.dark) #navbar-transition,html:not(.dark) #sidebar,html:not(.dark) #sidebar-content{background-color:var(--hub-shell-light)!important}html:not(.dark) .nav-tabs-item[data-active],html:not(.dark) mobile-nav-tabs-item[data-active],html:not(.dark) nav-dropdown-item[data-active]{background-color:transparent!important;box-shadow:none!important;color:var(--accent-purple)!important;font-weight:600!important}html:not(.dark) .nav-tabs-item[data-active] *,html:not(.dark) mobile-nav-tabs-item[data-active] *,html:not(.dark) nav-dropdown-item[data-active] *{color:inherit!important}html:not(.dark) #sidebar-content li:has(>a[aria-current=\"page\"]){background-color:transparent!important;box-shadow:none!important}html:not(.dark) #sidebar-content a[aria-current=\"page\"]{color:var(--accent-purple)!important;background-color:rgba(73, 55, 139, 0.1)!important;font-weight:600!important}html:not(.dark) #sidebar-content a[aria-current=\"page\"] *{color:inherit!important}html:not(.dark) toc-item[data-active],html:not(.dark) toc-item[data-active-deepest],html:not(.dark) toc-item[data-active] a,html:not(.dark) toc-item[data-active-deepest] a{background-color:transparent!important;color:var(--accent-purple)!important;font-weight:600!important}html:not(.dark) #header :where(h1,h2,h3,h4,h5,h6),html:not(.dark) #content-area :where(h1,h2,h3,h4,h5,h6){color:#151417!important}html:not(.dark) #navbar a[href*=\"comfy.org/cloud\"]{background-color:transparent!important;color:var(--accent-purple)!important;border-radius:0.75rem;box-shadow:inset 0 0 0 1px var(--accent-purple)!important}html:not(.dark) #navbar a[href*=\"comfy.org/cloud\"] span.absolute{background-color:transparent!important}html:not(.dark) #navbar a[href*=\"comfy.org/cloud\"] *{color:inherit!important}#sidebar .sticky.top-0.pointer-events-none.bg-linear-to-b{background-image:none!important}@media (min-width: 1024px){#navbar.is-not-custom.is-not-center+div:has(>#sidebar),.max-w-8xl.mx-auto.relative,.max-w-8xl.mx-auto{max-width:none!important;width:100%!important;margin-left:0!important;margin-right:0!important;padding-left:0!important;padding-right:0!important}#navbar [class*=\"px-12\"],#navbar [class*=\"mx-4\"]{padding-left:0!important;padding-right:1.5rem!important;margin-left:0!important;margin-right:0!important}#navbar a.select-none,#navbar .nav-logo{margin-left:1rem!important}#navbar .nav-tabs{padding-left:2rem!important}#sidebar{left:0!important;margin-left:0!important;box-shadow:none!important}#sidebar-content{margin-left:0!important;padding-left:1rem!important;box-sizing:border-box!important}#navbar,#navbar-transition{left:0!important;right:0!important;width:100%!important;max-width:none!important}#content-area{margin-left:0!important;max-width:none!important;width:100%!important;padding-left:18rem!important}#sidebar.sticky~#content-container #content-area{padding-left:2rem!important;padding-right:2rem!important}#content-container,#body-content{max-width:none!important;width:100%!important}:root{--content-width: 100%;--sidebar-width: 18rem}}@media (min-width: 1024px){nav#sidebar,#sidebar[style]{left:0!important;right:auto!important;margin-left:0!important;transform:none!important}#navbar li.navbar-link:has(a[href*=\"comfy.org/download\"]){margin-right:0!important}#navbar a[href*=\"comfy.org/download\"]{box-sizing:border-box;border:1px solid rgb(255 255 255 / 0.22);border-radius:0.75rem;padding:7px 0.875rem!important;color:#fff!important;font-size:0.875rem;line-height:1.25rem}html:not(.dark) #navbar a[href*=\"comfy.org/download\"]{border-color:rgb(0 0 0 / 0.16);color:#151417!important}#navbar a[href*=\"comfy.org/download\"]:hover{background:rgb(255 255 255 / 0.06)}html:not(.dark) #navbar a[href*=\"comfy.org/download\"]:hover{background:rgb(0 0 0 / 0.04)}#navbar li.navbar-link:has(a[href*=\"comfy.org/download\"])+.whitespace-nowrap,#navbar .flex.space-x-6>.whitespace-nowrap.hidden{margin-left:0.5rem!important}}body:has(.router-api-reference-marker) #content,body:has(.router-api-reference-marker) #header{max-width:48rem}body:has(.router-api-reference-marker) #content-area table{width:100%;table-layout:auto}body:has(.router-api-reference-marker) #content-area th,body:has(.router-api-reference-marker) #content-area td{min-width:4rem!important;overflow-wrap:anywhere}body:has(.router-api-reference-marker) #content-area table:has(th:nth-child(6)) th:nth-child(3),body:has(.router-api-reference-marker) #content-area table:has(th:nth-child(6)) td:nth-child(3){min-width:5rem!important}@media (max-width: 1535px){body:has(.router-api-reference-marker) #content-side-layout{display:none!important}}body:has(.router-provider-coverage-marker) #content,body:has(.router-provider-coverage-marker) #header{max-width:64rem}body:has(.router-provider-coverage-marker) #content-area table{width:100%;table-layout:auto}body:has(.router-provider-coverage-marker) #content-area th,body:has(.router-provider-coverage-marker) #content-area td{min-width:5rem!important;overflow-wrap:anywhere}body:has(.router-provider-coverage-marker) #content-area th:first-child,body:has(.router-provider-coverage-marker) #content-area td:first-child{min-width:12rem!important}body:has(.router-quickstart-marker) [data-component-part=\"card-content\"] [data-component-part=\"code-block-root\"][style*=\"height:190px\"],body:has(.router-quickstart-marker) [data-component-part=\"card-content\"] [data-component-part=\"code-block-root\"][style*=\"height: 190px\"]{height:86px!important}"},{"filePath":"samples-cards.css","content":".sample-card-grid{display:grid;gap:20px;grid-template-columns:repeat(2, minmax(0, 1fr));margin-top:28px}.sample-card{min-width:0;perspective:1200px}.sample-card-inner{height:565px;position:relative;transform-style:preserve-3d;transition:transform 560ms cubic-bezier(.2, .75, .3, 1)}.sample-card[data-flipped=\"true\"] .sample-card-inner{transform:rotateY(180deg)}.sample-card-face{backface-visibility:hidden;background:#fff;border:1px solid #e5e1eb;border-radius:12px;box-sizing:border-box;height:100%;inset:0;overflow:hidden;position:absolute;width:100%}.sample-card-front{display:flex;flex-direction:column}.sample-card-back{opacity:0;pointer-events:none;transform:rotateY(180deg);visibility:hidden}.sample-card[data-flipped=\"true\"] .sample-card-front{pointer-events:none;transition:visibility 0s linear 280ms;visibility:hidden}.sample-card[data-flipped=\"true\"][data-active-path=\"api\"] .sample-card-back[data-sample-path=\"api\"],.sample-card[data-flipped=\"true\"][data-active-path=\"endpoint\"] .sample-card-back[data-sample-path=\"endpoint\"]{opacity:1;pointer-events:auto;visibility:visible}.sample-card-preview{border-bottom:1px solid #e5e1eb;cursor:pointer;display:block;width:100%}.sample-card-body{display:flex;flex:1;flex-direction:column;padding:20px}.sample-card-body h2,.sample-path-body h2{color:#49378b;font-size:18px;font-weight:700;letter-spacing:-.02em;margin:0 0 8px}.sample-path-body h2{text-align:center}.sample-card-body>p{color:#5f5966;font-size:14px;line-height:1.55;margin:0;min-height:66px}.sample-card-actions{display:flex;gap:8px;margin-top:20px}.sample-card-actions button{background:#fff;border:1px solid #cfc8de;border-radius:6px;color:#49378b;cursor:pointer;flex:1;font-size:13px;font-weight:700;padding:10px 12px}.sample-card-links{border-top:1px solid #eeeaf1;display:flex;gap:8px;margin-top:16px;padding-top:12px}.sample-card-links a{color:#625b6c;font-size:12px;font-weight:650;text-decoration:none}.sample-card-links span{color:#b3adba}.sample-path-body{padding:20px}.sample-path-body>button{background:transparent;border:0;color:#625b6c;cursor:pointer;font-size:12px;font-weight:700;padding:0}.sample-path-eyebrow{color:#857a9e;font-size:10px;font-weight:700;letter-spacing:.08em;margin:19px 0 5px;text-align:center;text-transform:uppercase}.sample-path-body>p:not(.sample-path-eyebrow){color:#5f5966;font-size:12px;line-height:1.5;margin:0 0 15px}.sample-path-steps{display:grid;gap:8px}.sample-path-step{align-items:center;background:#faf9fc;border:1px solid #e5e1ea;border-radius:8px;display:flex;gap:10px;padding:10px 11px}.sample-path-number{align-items:center;background:#49378b;border-radius:999px;color:#fff;display:inline-flex;flex:0 0 21px;font-size:11px;font-weight:700;height:21px;justify-content:center}.sample-path-copy{flex:1;min-width:0}.sample-path-copy strong{color:#312c36;display:block;font-size:12px}.sample-path-copy span{color:#706a75;display:block;font-size:11px;line-height:1.35;margin-top:2px}.sample-path-step a{color:#49378b;flex:0 0 auto;font-size:11px;font-weight:700;text-decoration:none}@media (max-width: 768px){.sample-card-grid{grid-template-columns:1fr}.sample-card-inner{height:clamp(620px, 180vw, 760px)}}"}],"page":{"pagePath":"ko/api-reference/router/comfy-router/read-one-partner-models-catalog-entry-by-canonical-model-id","slug":"/ko/api-reference/router/comfy-router/read-one-partner-models-catalog-entry-by-canonical-model-id","pageMetadata":{"title":"Read one partner model's catalog entry by canonical model ID.","description":"Per-model detail for a single Comfy Router model, so a caller can check one model without walking the whole paginated catalog. The SDKs use it to look a model up immediately before invoking it.","deprecated":null,"version":null,"openapi":"/router-openapi.yaml get /v2/models/{provider}/{model}","href":"/ko/api-reference/router/comfy-router/read-one-partner-models-catalog-entry-by-canonical-model-id","autogeneratedByOpenApi":true},"description":{"compiledSource":"\"use strict\";\nconst {jsx: _jsx} = arguments[0];\nconst {useMDXComponents: _provideComponents} = arguments[0];\nfunction _createMdxContent(props) {\n const _components = {\n p: \"p\",\n ..._provideComponents(),\n ...props.components\n };\n return _jsx(_components.p, {\n children: \"Per-model detail for a single Comfy Router model, so a caller can check one model without walking the whole paginated catalog. The SDKs use it to look a model up immediately before invoking it.\"\n });\n}\nfunction MDXContent(props = {}) {\n const {wrapper: MDXLayout} = {\n ..._provideComponents(),\n ...props.components\n };\n return MDXLayout ? _jsx(MDXLayout, {\n ...props,\n children: _jsx(_createMdxContent, {\n ...props\n })\n }) : _createMdxContent(props);\n}\nreturn {\n default: MDXContent\n};\n","frontmatter":{},"scope":{}},"pageType":"default","mdx":{"mdxSource":{"compiledSource":"\"use strict\";const{Fragment:_Fragment,jsx:_jsx}=arguments[0];const{useMDXComponents:_provideComponents}=arguments[0];function _createMdxContent(props){return _jsx(_Fragment,{})}function MDXContent(props={}){const{wrapper:MDXLayout}={..._provideComponents(),...props.components};return MDXLayout?_jsx(MDXLayout,{...props,children:_jsx(_createMdxContent,{...props})}):_createMdxContent(props)}return{default:MDXContent}","frontmatter":{},"scope":{"config":{},"pageMetadata":{"title":"Read one partner model's catalog entry by canonical model ID.","description":"Per-model detail for a single Comfy Router model, so a caller can check one model without walking the whole paginated catalog. The SDKs use it to look a model up immediately before invoking it.","deprecated":null,"version":null,"openapi":"/router-openapi.yaml get /v2/models/{provider}/{model}","href":"/ko/api-reference/router/comfy-router/read-one-partner-models-catalog-entry-by-canonical-model-id","autogeneratedByOpenApi":true}}},"mdxSourceWithNoJs":null},"mdxExtracts":{"tableOfContents":[],"codeExamples":{}},"jsLinks":["/_mintlify/custom/dripart/9d6bf2b2531e904c/giscus-comments.js","/_mintlify/custom/dripart/bd0341946f3c75a6/syft.js","/_mintlify/custom/dripart/042392a43b5e681e/samples-cards.js"],"openApiReferenceData":{"operation":{"summary":"Read one partner model's catalog entry by canonical model ID.","description":"Per-model detail for a single Comfy Router model, so a caller can check one model without walking the whole paginated catalog. The SDKs use it to look a model up immediately before invoking it.","operationId":"getRouterModel","tags":["Comfy Router"],"security":["a4806511-f591-4bf5-84f7-24b03a60353f","0d5bd07c-4671-4644-bb5e-411e019d9b9e"],"parameters":["1cb223e2-e211-49c1-97d2-e2dd26063c46","776b67f8-abaf-474a-b1a7-59d1ab742e9c","ca12f3bb-b179-4b99-bd5b-058b2ff31f6e"],"responses":{"200":"33f67881-ab37-4c58-a93b-1803c498e837","304":"95e1faa6-d86a-475d-af4f-cebfe907ac8d","401":"b9a865cb-21a9-4245-a9c9-2f8782ae2eaa","403":"108a7ca4-76b1-424a-8ae9-44203589422b","404":"5a95d66a-a988-4374-982b-8431b52c5c06","429":"d150b00d-b13c-4f8c-a157-8aea0e407b73","503":"1311734b-13bb-4c01-a675-facb770152fa"},"method":"get","type":"path","servers":["bf9722b0-5952-4eeb-9e69-c43ede83ce5a"],"path":"/v2/models/{provider}/{model}","baseUrlOptions":["https://api.comfy.org"],"title":"Read one partner model's catalog entry by canonical model ID.","codeSamples":[],"requiredOnlyExamples":false,"requestExampleType":"generated","responseExampleType":"generated"},"dependencies":{"parameters":{"1cb223e2-e211-49c1-97d2-e2dd26063c46":{"name":"provider","in":"path","required":true,"description":"Lowercase provider segment of the canonical `{provider}/{model}` model ID - the partner whose model is being run.","schema":{"type":"string","description":"Lowercase provider segment of the canonical `{provider}/{model}` model ID - the partner whose model is being run.\nLowercase `provider` segment of the canonical `{provider}/{model}` model ID - the partner whose model is being addressed. The invocation route's `provider` path parameter and a catalog entry's `provider` field both reference this one schema, which is what keeps the listed IDs and the accepted IDs from drifting apart.","pattern":"^[a-z0-9]+([._-][a-z0-9]+)*$","maxLength":64,"example":"bfl","isRequired":true,"uniqueKey":"","typeLabel":"string"}},"776b67f8-abaf-474a-b1a7-59d1ab742e9c":{"name":"model","in":"path","required":true,"description":"Lowercase model segment of the canonical `{provider}/{model}` model ID - the model to run within that provider.","schema":{"type":"string","description":"Lowercase model segment of the canonical `{provider}/{model}` model ID - the model to run within that provider.\nLowercase `model` segment of the canonical `{provider}/{model}` model ID - the model to run within that provider. Shared by the invocation route's `model` path parameter and a catalog entry's `model` field, for the same no-drift reason as `RouterProviderSegment`.","pattern":"^[a-z0-9]+([._-][a-z0-9]+)*$","maxLength":128,"example":"flux-2-pro","isRequired":true,"uniqueKey":"","typeLabel":"string"}},"ca12f3bb-b179-4b99-bd5b-058b2ff31f6e":{"in":"header","name":"If-None-Match","required":false,"description":"The `ETag` a caller holds from an earlier `200`. When it matches the current entry (RFC 9110 weak comparison; `*` matches any current entry) the answer is a bodyless `304` carrying the same `ETag`, otherwise the full entry.","schema":{"type":"string","isRequired":false,"description":"The `ETag` a caller holds from an earlier `200`. When it matches the current entry (RFC 9110 weak comparison; `*` matches any current entry) the answer is a bodyless `304` carrying the same `ETag`, otherwise the full entry.","uniqueKey":"","typeLabel":"string"}}},"responses":{"33f67881-ab37-4c58-a93b-1803c498e837":{"description":"OK - the model's catalog entry.","headers":{"X-Comfy-Request-Id":{"description":"Server-generated identifier for this call, present on every Router response - success, 4xx and 5xx alike, because an error response is exactly when a user needs an id to quote in a support request. The same value is written into the call's usage/audit event, which is what lets a complaint about a charge be joined to the charge itself instead of searched for by timestamp.","required":true,"schema":{"type":"string","format":"uuid","example":"6f1a1a6e-6a53-4a5f-9d3a-2b3b0a1f9c21"}},"ETag":{"description":"Strong entity tag over the served body's bytes, for `GET /v2/models` and `GET /v2/models/{provider}/{model}`. A caller that re-reads the catalog should store this value and send it back as `If-None-Match` to get a `304` instead of the body.","required":true,"schema":{"type":"string","example":"\"6b8c1f2e0a9d4c3b5e7f8a1b2c3d4e5f60718293a4b5c6d7e8f90a1b2c3d4e5f\""}},"Cache-Control":{"description":"Freshness directives for a catalog page or entry. `private` because the answer is decided per credential (the response also carries `Vary: Authorization, X-API-Key`), so a shared cache must not hold it, and `must-revalidate` so a stale copy is revalidated against the `ETag` rather than served on. Error responses on these routes are `private, no-store` instead.","required":false,"schema":{"type":"string","example":"private, max-age=300, must-revalidate"}}},"content":{"application/json":{"schema":{"type":"object","description":"Per-model detail for one Comfy Router model: everything the catalog listing reports for it, plus the per-model fields that only the single-model route carries.","required":["id","provider","model","billing"],"properties":{"id":{"type":"string","description":"A canonical Comfy Router model ID, `{provider}/{model}` - exactly the value that addresses the model on `POST /v2/models/{provider}/{model}`, so a caller can interpolate it into that path without re-deriving it from anything. Its `pattern` is `RouterProviderSegment` and `RouterModelSegment` joined by a single `/`, and `maxLength` is their sum plus that separator.","pattern":"^[a-z0-9]+([._-][a-z0-9]+)*/[a-z0-9]+([._-][a-z0-9]+)*$","maxLength":193,"example":"bfl/flux-2-pro","isRequired":true,"uniqueKey":"id","typeLabel":"string"},"provider":{"type":"string","description":"Lowercase `provider` segment of the canonical `{provider}/{model}` model ID - the partner whose model is being addressed. The invocation route's `provider` path parameter and a catalog entry's `provider` field both reference this one schema, which is what keeps the listed IDs and the accepted IDs from drifting apart.","pattern":"^[a-z0-9]+([._-][a-z0-9]+)*$","maxLength":64,"example":"bfl","isRequired":true,"uniqueKey":"provider","typeLabel":"string"},"model":{"type":"string","description":"Lowercase `model` segment of the canonical `{provider}/{model}` model ID - the model to run within that provider. Shared by the invocation route's `model` path parameter and a catalog entry's `model` field, for the same no-drift reason as `RouterProviderSegment`.","pattern":"^[a-z0-9]+([._-][a-z0-9]+)*$","maxLength":128,"example":"flux-2-pro","isRequired":true,"uniqueKey":"model","typeLabel":"string"},"billing":{"type":"object","description":"Per-model billing facts a caller needs before invoking - not prices. Usage and cost figures never appear here.","properties":{"charges_on_policy_rejection":{"type":"string","description":"Whether a call this model refuses on content-policy grounds is nevertheless charged to the caller. Providers differ, the difference is invisible at call time, and a user who sees an error and a charge for the same call has no way to have known - so it is stated per model, before the call, rather than left to per-provider folklore. When it is `yes`, a `content_policy_violation` error on the synchronous route can carry `X-Comfy-Credits-Used`: it does when the provider refused the model's generated output and Comfy recorded usage for that refused generation, and carries that amount. An input-side refusal, a same-key replay (`Idempotent-Replayed: true`), and a charge too small to show in the header's two decimals do not carry it; a refusal without the header is not reported, not proof it was free.","example":"unknown","isRequired":true,"uniqueKey":"billing.charges_on_policy_rejection","typeLabel":"string"}},"required":["charges_on_policy_rejection"],"isRequired":true,"uniqueKey":"billing","typeLabel":"object"},"schema_etag":{"type":"string","description":"The current strong `ETag` of this model's `GET /v2/models/{provider}/{model}/openapi.json` document. Send it as `If-None-Match` on that read to get a `304` while the schema is unchanged, or compare it with the value seen last time to learn which models' schemas changed without fetching every document. Absent whenever that read would not answer `200` for this caller at this moment: the schema service is not available, the model's document cannot be rendered, or the model stopped being available to this caller while the response was being built. An absent tag is not a schema change; re-read the model's document to learn its current tag.","example":"\"9f2c1e0b7a4d3c6e8f5a2b1d0c9e8f7a6b5c4d3e2f1a0b9c8d7e6f5a4b3c2d1e\"","uniqueKey":"schema_etag","typeLabel":"string"},"input_schema_url":{"type":"string","format":"uri","pattern":"^https://","maxLength":2048,"description":"Pointer to this model's input schema document - the description of the body `POST /v2/models/{provider}/{model}` accepts for this model. Only the pointer is part of this contract: the document it addresses is authored separately. Absent when no schema has been authored for the model.","uniqueKey":"input_schema_url","typeLabel":"string\u003curi>"}},"uniqueKey":"","typeLabel":"object"},"examples":{"Example":{"title":"Example","value":{"id":"bfl/flux-2-pro","provider":"bfl","model":"flux-2-pro","billing":{"charges_on_policy_rejection":"unknown"},"schema_etag":"\"9f2c1e0b7a4d3c6e8f5a2b1d0c9e8f7a6b5c4d3e2f1a0b9c8d7e6f5a4b3c2d1e\"","input_schema_url":"\u003cstring>"}}},"exampleType":"generated"}},"exampleType":"generated"},"95e1faa6-d86a-475d-af4f-cebfe907ac8d":{"description":"Not Modified - the entry is unchanged since the `ETag` the caller sent in `If-None-Match`. No body is returned.","headers":{"X-Comfy-Request-Id":{"description":"Server-generated identifier for this call, present on every Router response - success, 4xx and 5xx alike, because an error response is exactly when a user needs an id to quote in a support request. The same value is written into the call's usage/audit event, which is what lets a complaint about a charge be joined to the charge itself instead of searched for by timestamp.","required":true,"schema":{"type":"string","format":"uuid","example":"6f1a1a6e-6a53-4a5f-9d3a-2b3b0a1f9c21"}},"ETag":{"description":"Strong entity tag over the served body's bytes, for `GET /v2/models` and `GET /v2/models/{provider}/{model}`. A caller that re-reads the catalog should store this value and send it back as `If-None-Match` to get a `304` instead of the body.","required":true,"schema":{"type":"string","example":"\"6b8c1f2e0a9d4c3b5e7f8a1b2c3d4e5f60718293a4b5c6d7e8f90a1b2c3d4e5f\""}},"Cache-Control":{"description":"Freshness directives for a catalog page or entry. `private` because the answer is decided per credential (the response also carries `Vary: Authorization, X-API-Key`), so a shared cache must not hold it, and `must-revalidate` so a stale copy is revalidated against the `ETag` rather than served on. Error responses on these routes are `private, no-store` instead.","required":false,"schema":{"type":"string","example":"private, max-age=300, must-revalidate"}}},"content":{"_mintlify/placeholder":{"schema":{"type":"object","description":""}}}},"b9a865cb-21a9-4245-a9c9-2f8782ae2eaa":{"description":"A Router request-level failure - the request never reached the model, or failed for a reason the model itself did not report. The body is `RouterErrorResponse` and the bucket is repeated on `X-Comfy-Error-Type`.","headers":{"X-Comfy-Error-Type":{"description":"Coarse, machine-readable bucket for the failure, set by Router on every error response. It carries the same value as `RouterErrorResponse.error_type`, and on the `422` it is the only machine-readable bucket, because that body is the FastAPI `detail[]` shape and has no `error_type` field of its own. A client can therefore branch on this header alone, before deciding which of the two Router error bodies it received.","required":true,"schema":{"type":"string","description":"Coarse, machine-readable bucket for a Router failure, mirrored on the `X-Comfy-Error-Type` response header so a caller can branch without parsing the body. The set is closed at twenty values: the six request-level buckets `invalid_input`, `content_policy_violation`, `provider_error`, `provider_timeout`, `insufficient_credits` and `model_not_found`, plus the transport-level `unauthorized`, `forbidden`, `concurrency_limit_exceeded`, `client_disconnected`, `internal_error`, `deadline_exceeded`, `not_enabled`, `service_unavailable`, `rate_limited`, `cancelled`, `queue_timeout`, `request_not_found`, `queue_backlog_full` and `result_expired`. Closed describes the set as documented today, not a bound that holds forever: the set is expected to grow, which is why this is deliberately a plain string and not an `enum`, so a client must treat an unrecognised value as `internal_error` rather than switch exhaustively over the list above and break on the next addition.","example":"invalid_input","x-comfy-error-types":[{"value":"invalid_input","tier":"request","meaning":"The request was rejected before it reached the model - a malformed body, a malformed or expired pagination cursor, an input the model's own schema does not accept, or an `Idempotency-Key` that cannot serve this request (already used for a different request - the method, the path and query, or the body differ - or already consumed by a call whose response cannot be replayed). Sent with `409` in the key cases and with `400`/`422` in the others; the status says which, and the key cases are the ones answered by using a new key rather than by editing the request."},{"value":"content_policy_violation","tier":"request","meaning":"The provider refused the request on content-policy grounds. The refusal is deterministic: re-sending the same input will be refused again."},{"value":"provider_error","tier":"request","meaning":"The partner provider reported a failure of its own, or returned a response Router could not interpret as a result."},{"value":"provider_timeout","tier":"request","meaning":"The partner provider did not answer within its deadline. This bucket is the provider timing out and never Router's own server deadline, which is reported as `deadline_exceeded` - the two share `504` and are separated because they name different causes: this one says the partner failed, that one says Comfy stopped holding the connection."},{"value":"insufficient_credits","tier":"request","meaning":"The calling workspace does not have enough credits to run the model."},{"value":"model_not_found","tier":"request","meaning":"The `{provider}/{model}` ID names no model Router can run: an unknown provider, an unenrolled id, one the catalog has retired past its sunset date, or a catalogued ID the provider does not currently serve for Comfy. A retired id's `detail` reads `\u003cid> was retired on \u003cYYYY-MM-DD>; use \u003csuccessor>` when a successor is recorded and not withheld, or just `\u003cid> was retired on \u003cYYYY-MM-DD>` when it is not, instead of a suggestion list; the successor named for a retired id is always a live catalog ID you can re-point the call at, and a successor is dropped from `detail` either because the table records none, or because the recorded one is currently withheld behind an embargo the caller cannot see. A model whose sunset is still in the future is not withdrawn: it stays listed by `GET /v2/models` and stays runnable until the date, so a listing taken today remains the answer to what runs today. Otherwise `detail` carries up to three suggestions drawn from the models the caller is entitled to see, except for a catalogued ID the provider does not currently serve for Comfy, whose response carries no suggestions."},{"value":"unauthorized","tier":"transport","meaning":"The request carried no usable credential."},{"value":"forbidden","tier":"transport","meaning":"The credential is valid but is not entitled to this model or this operation."},{"value":"concurrency_limit_exceeded","tier":"transport","meaning":"The workspace already has as many calls in flight as it is allowed; retry once one of them finishes. It carries one further condition on the run route, on a `409` rather than the `429` above: another call is already in flight for the `Idempotency-Key` this request presented. Re-send the same key after `Retry-After` seconds to collect that call's result."},{"value":"client_disconnected","tier":"transport","meaning":"The caller closed the connection before Router could return a result. It is logged rather than delivered - there is no socket left to write it to - and it is an attribution, not a billing outcome: a provider generation that completed is billed regardless of whether the caller received the response."},{"value":"internal_error","tier":"transport","meaning":"Router itself failed. It is also the value a client should treat any unrecognized bucket as, so a later addition to the set does not break a client generated before it."},{"value":"deadline_exceeded","tier":"transport","meaning":"Comfy stopped holding the connection at its own configured bound before an answer arrived. It shares `504` with `provider_timeout` and the pair says which side ran out of time; this one is Comfy's own bound, so nothing about the request was rejected and the same request may be retried. It says nothing about the charge: a provider generation that completed is billed regardless of whether the caller received the response. Retry it with the same `Idempotency-Key`: when the provider had already accepted the generation, the retry collects that generation rather than dispatching another, and a `Retry-After` on the `504` says when to ask."},{"value":"not_enabled","tier":"transport","meaning":"Comfy Router is not switched on for this caller yet. Nothing about the request is wrong and the model exists, which is why this is not `model_not_found`; it shares `403` with `forbidden` and is not the same thing, because `forbidden` is an entitlement decision about the caller while this is a state of the rollout. It is terminal: do not retry, and do not treat it as an outage. The one exception to \"about the caller\" is the queued submit, which also answers `not_enabled` for a model whose partner answers a generation directly as bytes: that model cannot yet be queued, so it is the model and not the caller that is refused, nothing is queued or charged, and the synchronous route `POST /v2/models/{provider}/{model}` runs it instead."},{"value":"service_unavailable","tier":"transport","meaning":"A service Comfy Router depends on is temporarily unavailable and the caller did nothing wrong. Retry it with backoff: it is the one bucket here whose condition clears on its own, without the caller changing the request and without a concurrency slot freeing, which is what distinguishes it from the other retryable answers (`concurrency_limit_exceeded`, `deadline_exceeded`). It is separate from `internal_error` - which is a `500` and means Router itself failed - so a client can tell \"come back shortly\" from \"this call is not going to work\"."},{"value":"rate_limited","tier":"transport","meaning":"The caller has spent an allowance measured over a window and must wait for that window to roll. It shares `429` with `concurrency_limit_exceeded` and is not the same thing: that one clears the moment one of the caller's own in-flight calls finishes, so retrying in seconds is right, whereas nothing the caller does drains this one early. `detail` names the window, and `Retry-After` the seconds to wait."},{"value":"cancelled","tier":"transport","meaning":"A queued request was withdrawn — through the cancel route, or by an operator — before it produced a result; it is terminal, and it is not by itself a statement about the charge. Cancelling stops Comfy waiting and it does not always stop the partner working, so a request cancelled while it was still `IN_QUEUE` was never dispatched and cannot be charged, whereas one cancelled after it was admitted may still be charged — a partner generation that completes is charged whether or not anyone collected it, which is why the cancel route calls the ask a request rather than a guarantee. It is not `client_disconnected`: that one says nobody is listening any more while a generation may still be running and billable, whereas this says the request itself was withdrawn. A caller polling the status read sees `200` with this in the body, because the request ended and so the read succeeded. Collecting the result of such a request answers `409` in Router's error envelope: that read also worked, and what it found is a request whose terminal state - the caller's own decision - leaves nothing to return. It is deliberately not `410`, which on that route means the result aged out of its retention window, and not a `5xx`, which would report the caller's own cancellation as a Router fault and read to a polling client as worth retrying."},{"value":"queue_timeout","tier":"transport","meaning":"A queued request waited past its queue timeout without ever being admitted. Terminal, unbilled, and it never took a concurrency slot — the job never reached a provider. Deliberately not `deadline_exceeded`, which is the synchronous route's connection bound: a `deadline_exceeded` generation may be running and billable, whereas this one provably never started. It is returned under `504`, which it shares with `provider_timeout` and `deadline_exceeded` because a status can only say that a clock ran out; which clock - the partner's, Comfy's connection bound, or the queue's admission bound - is what `error_type` carries. The request itself is terminal, so submit a new one rather than re-reading this one."},{"value":"request_not_found","tier":"transport","meaning":"The `request_id` names no request of the caller's under this model. It is the second of the two conditions the queued reads' `404` covers; the first is the `{provider}/{model}` ID resolving to no partner model, which is `model_not_found` and carries fuzzy model suggestions. It also covers the right-id / wrong-model URL the path shape refuses, and it is deliberately indistinguishable from a request in another workspace, so a probe with a guessed id learns nothing. A request that has merely aged out of its retention window is `410`, not this."},{"value":"queue_backlog_full","tier":"transport","meaning":"The caller already has too many queued requests waiting to run, so this submit was refused. It shares `429` with `concurrency_limit_exceeded` and is not the same thing: that one is the synchronous route's answer for too many calls in flight at once, whereas the queue accepts a submit at that limit and parks it, and this bucket is the separate bound on how many a caller may leave waiting so that parking cannot mean enqueuing without end. It clears as the caller's own queued requests finish, so retry once some of them complete."},{"value":"result_expired","tier":"transport","meaning":"The request existed and finished, but its result is no longer stored, so the collect has nothing to return. It is returned under `410` and is permanent for that id: re-reading will answer the same way, so do not retry it. It is deliberately not `request_not_found`, which would tell you the id was never valid and invite re-submitting a generation that has already run. Running the model again means submitting a new request. For a workspace under a zero-data-retention agreement, a queued request's result is not kept after it is delivered: it is removed shortly after the first collect, and an uncollected result is removed after a grace period once the request finishes, so store the result on your side when you first collect it."}]}},"X-Comfy-Request-Id":{"description":"Server-generated identifier for this call, present on every Router response - success, 4xx and 5xx alike, because an error response is exactly when a user needs an id to quote in a support request. The same value is written into the call's usage/audit event, which is what lets a complaint about a charge be joined to the charge itself instead of searched for by timestamp.","required":true,"schema":{"type":"string","format":"uuid","example":"6f1a1a6e-6a53-4a5f-9d3a-2b3b0a1f9c21"}}},"content":{"application/json":{"schema":{"type":"object","description":"Router's request-level error body: what is returned when the request never reached the model, or failed for a reason the model itself did not report - auth, quota, an unknown model ID, or provider transport. A model-level validation failure has its own shape, `RouterValidationErrorResponse`, because flattening a FastAPI `detail[]` array into this `detail` string would destroy the per-field granularity an SDK branches on.","properties":{"detail":{"type":"string","description":"Human-readable description of the failure, safe to surface to an end user. Not machine-parsed - branch on `error_type` instead. For `model_not_found` on a retired model, `detail` reads `\u003cid> was retired on \u003cYYYY-MM-DD>; use \u003csuccessor>` when a successor is recorded and visible to the caller, or just `\u003cid> was retired on \u003cYYYY-MM-DD>` when it is not, instead of the usual suggestion list. A successor named here is always a live catalog ID the call can be re-pointed at. A model whose sunset date is still in the future is not retired: it stays listed by `GET /v2/models` and stays runnable until that date. Like the rest of `detail`, this retirement wording is for display and carries no compatibility guarantee.","isRequired":true,"uniqueKey":"detail","typeLabel":"string"},"error_type":{"type":"string","description":"Coarse, machine-readable bucket for a Router failure, mirrored on the `X-Comfy-Error-Type` response header so a caller can branch without parsing the body. The set is closed at twenty values: the six request-level buckets `invalid_input`, `content_policy_violation`, `provider_error`, `provider_timeout`, `insufficient_credits` and `model_not_found`, plus the transport-level `unauthorized`, `forbidden`, `concurrency_limit_exceeded`, `client_disconnected`, `internal_error`, `deadline_exceeded`, `not_enabled`, `service_unavailable`, `rate_limited`, `cancelled`, `queue_timeout`, `request_not_found`, `queue_backlog_full` and `result_expired`. Closed describes the set as documented today, not a bound that holds forever: the set is expected to grow, which is why this is deliberately a plain string and not an `enum`, so a client must treat an unrecognised value as `internal_error` rather than switch exhaustively over the list above and break on the next addition.","example":"invalid_input","x-comfy-error-types":[{"value":"invalid_input","tier":"request","meaning":"The request was rejected before it reached the model - a malformed body, a malformed or expired pagination cursor, an input the model's own schema does not accept, or an `Idempotency-Key` that cannot serve this request (already used for a different request - the method, the path and query, or the body differ - or already consumed by a call whose response cannot be replayed). Sent with `409` in the key cases and with `400`/`422` in the others; the status says which, and the key cases are the ones answered by using a new key rather than by editing the request."},{"value":"content_policy_violation","tier":"request","meaning":"The provider refused the request on content-policy grounds. The refusal is deterministic: re-sending the same input will be refused again."},{"value":"provider_error","tier":"request","meaning":"The partner provider reported a failure of its own, or returned a response Router could not interpret as a result."},{"value":"provider_timeout","tier":"request","meaning":"The partner provider did not answer within its deadline. This bucket is the provider timing out and never Router's own server deadline, which is reported as `deadline_exceeded` - the two share `504` and are separated because they name different causes: this one says the partner failed, that one says Comfy stopped holding the connection."},{"value":"insufficient_credits","tier":"request","meaning":"The calling workspace does not have enough credits to run the model."},{"value":"model_not_found","tier":"request","meaning":"The `{provider}/{model}` ID names no model Router can run: an unknown provider, an unenrolled id, one the catalog has retired past its sunset date, or a catalogued ID the provider does not currently serve for Comfy. A retired id's `detail` reads `\u003cid> was retired on \u003cYYYY-MM-DD>; use \u003csuccessor>` when a successor is recorded and not withheld, or just `\u003cid> was retired on \u003cYYYY-MM-DD>` when it is not, instead of a suggestion list; the successor named for a retired id is always a live catalog ID you can re-point the call at, and a successor is dropped from `detail` either because the table records none, or because the recorded one is currently withheld behind an embargo the caller cannot see. A model whose sunset is still in the future is not withdrawn: it stays listed by `GET /v2/models` and stays runnable until the date, so a listing taken today remains the answer to what runs today. Otherwise `detail` carries up to three suggestions drawn from the models the caller is entitled to see, except for a catalogued ID the provider does not currently serve for Comfy, whose response carries no suggestions."},{"value":"unauthorized","tier":"transport","meaning":"The request carried no usable credential."},{"value":"forbidden","tier":"transport","meaning":"The credential is valid but is not entitled to this model or this operation."},{"value":"concurrency_limit_exceeded","tier":"transport","meaning":"The workspace already has as many calls in flight as it is allowed; retry once one of them finishes. It carries one further condition on the run route, on a `409` rather than the `429` above: another call is already in flight for the `Idempotency-Key` this request presented. Re-send the same key after `Retry-After` seconds to collect that call's result."},{"value":"client_disconnected","tier":"transport","meaning":"The caller closed the connection before Router could return a result. It is logged rather than delivered - there is no socket left to write it to - and it is an attribution, not a billing outcome: a provider generation that completed is billed regardless of whether the caller received the response."},{"value":"internal_error","tier":"transport","meaning":"Router itself failed. It is also the value a client should treat any unrecognized bucket as, so a later addition to the set does not break a client generated before it."},{"value":"deadline_exceeded","tier":"transport","meaning":"Comfy stopped holding the connection at its own configured bound before an answer arrived. It shares `504` with `provider_timeout` and the pair says which side ran out of time; this one is Comfy's own bound, so nothing about the request was rejected and the same request may be retried. It says nothing about the charge: a provider generation that completed is billed regardless of whether the caller received the response. Retry it with the same `Idempotency-Key`: when the provider had already accepted the generation, the retry collects that generation rather than dispatching another, and a `Retry-After` on the `504` says when to ask."},{"value":"not_enabled","tier":"transport","meaning":"Comfy Router is not switched on for this caller yet. Nothing about the request is wrong and the model exists, which is why this is not `model_not_found`; it shares `403` with `forbidden` and is not the same thing, because `forbidden` is an entitlement decision about the caller while this is a state of the rollout. It is terminal: do not retry, and do not treat it as an outage. The one exception to \"about the caller\" is the queued submit, which also answers `not_enabled` for a model whose partner answers a generation directly as bytes: that model cannot yet be queued, so it is the model and not the caller that is refused, nothing is queued or charged, and the synchronous route `POST /v2/models/{provider}/{model}` runs it instead."},{"value":"service_unavailable","tier":"transport","meaning":"A service Comfy Router depends on is temporarily unavailable and the caller did nothing wrong. Retry it with backoff: it is the one bucket here whose condition clears on its own, without the caller changing the request and without a concurrency slot freeing, which is what distinguishes it from the other retryable answers (`concurrency_limit_exceeded`, `deadline_exceeded`). It is separate from `internal_error` - which is a `500` and means Router itself failed - so a client can tell \"come back shortly\" from \"this call is not going to work\"."},{"value":"rate_limited","tier":"transport","meaning":"The caller has spent an allowance measured over a window and must wait for that window to roll. It shares `429` with `concurrency_limit_exceeded` and is not the same thing: that one clears the moment one of the caller's own in-flight calls finishes, so retrying in seconds is right, whereas nothing the caller does drains this one early. `detail` names the window, and `Retry-After` the seconds to wait."},{"value":"cancelled","tier":"transport","meaning":"A queued request was withdrawn — through the cancel route, or by an operator — before it produced a result; it is terminal, and it is not by itself a statement about the charge. Cancelling stops Comfy waiting and it does not always stop the partner working, so a request cancelled while it was still `IN_QUEUE` was never dispatched and cannot be charged, whereas one cancelled after it was admitted may still be charged — a partner generation that completes is charged whether or not anyone collected it, which is why the cancel route calls the ask a request rather than a guarantee. It is not `client_disconnected`: that one says nobody is listening any more while a generation may still be running and billable, whereas this says the request itself was withdrawn. A caller polling the status read sees `200` with this in the body, because the request ended and so the read succeeded. Collecting the result of such a request answers `409` in Router's error envelope: that read also worked, and what it found is a request whose terminal state - the caller's own decision - leaves nothing to return. It is deliberately not `410`, which on that route means the result aged out of its retention window, and not a `5xx`, which would report the caller's own cancellation as a Router fault and read to a polling client as worth retrying."},{"value":"queue_timeout","tier":"transport","meaning":"A queued request waited past its queue timeout without ever being admitted. Terminal, unbilled, and it never took a concurrency slot — the job never reached a provider. Deliberately not `deadline_exceeded`, which is the synchronous route's connection bound: a `deadline_exceeded` generation may be running and billable, whereas this one provably never started. It is returned under `504`, which it shares with `provider_timeout` and `deadline_exceeded` because a status can only say that a clock ran out; which clock - the partner's, Comfy's connection bound, or the queue's admission bound - is what `error_type` carries. The request itself is terminal, so submit a new one rather than re-reading this one."},{"value":"request_not_found","tier":"transport","meaning":"The `request_id` names no request of the caller's under this model. It is the second of the two conditions the queued reads' `404` covers; the first is the `{provider}/{model}` ID resolving to no partner model, which is `model_not_found` and carries fuzzy model suggestions. It also covers the right-id / wrong-model URL the path shape refuses, and it is deliberately indistinguishable from a request in another workspace, so a probe with a guessed id learns nothing. A request that has merely aged out of its retention window is `410`, not this."},{"value":"queue_backlog_full","tier":"transport","meaning":"The caller already has too many queued requests waiting to run, so this submit was refused. It shares `429` with `concurrency_limit_exceeded` and is not the same thing: that one is the synchronous route's answer for too many calls in flight at once, whereas the queue accepts a submit at that limit and parks it, and this bucket is the separate bound on how many a caller may leave waiting so that parking cannot mean enqueuing without end. It clears as the caller's own queued requests finish, so retry once some of them complete."},{"value":"result_expired","tier":"transport","meaning":"The request existed and finished, but its result is no longer stored, so the collect has nothing to return. It is returned under `410` and is permanent for that id: re-reading will answer the same way, so do not retry it. It is deliberately not `request_not_found`, which would tell you the id was never valid and invite re-submitting a generation that has already run. Running the model again means submitting a new request. For a workspace under a zero-data-retention agreement, a queued request's result is not kept after it is delivered: it is removed shortly after the first collect, and an uncollected result is removed after a grace period once the request finishes, so store the result on your side when you first collect it."}],"isRequired":true,"uniqueKey":"error_type","typeLabel":"string"},"upstream_detail":{"type":"string","description":"A bounded, sanitized reason the model provider gave for rejecting the request, present only when `error_type` is `invalid_input` and `X-Comfy-Upstream-Status` is a provider `4xx` or `2xx` - i.e. the provider refused the request as malformed and said why. Usually that status is a `4xx`; it is a `2xx` for a provider that reports a rejected generation inside a success envelope (a BytePlus failed-task poll is HTTP `200` with the reason in its body). Absent on every other failure, including provider `5xx`, transport failures, content-policy refusals and any refusal Router raised about itself. It mirrors the `X-Comfy-Upstream-Detail` header. The queued collect (`GET /v2/models/{provider}/{model}/requests/{request_id}`) of a run that ended `invalid_input` carries the same reason in this field on its first collect, which then deletes it from the request: a later collect normally answers the same `error_type` and `detail` without it, so read it from the first collect. That read sends neither header.","uniqueKey":"upstream_detail","typeLabel":"string"},"refusal_subject":{"type":"string","description":"Which input or output a content-policy refusal was about, as a Router-level closed vocabulary: `input`, `output`, `input_text`, `input_image`, `input_video`, `input_audio`, `output_text`, `output_image`, `output_video`, `output_audio`. The bare `input` / `output` values name the side when the provider did not name a modality. Present only when `error_type` is `content_policy_violation` and the provider named the refused subject with a machine-readable code; absent otherwise. Never provider text. Named today for BytePlus, Runway, BFL, Gemini, Veo, Vertex, xAI and Wan refusals, and for the MiniMax Router's Nano Banana legs' Gemini refusals; a provider whose refusal does not say which side it was about leaves it absent. It mirrors the `X-Comfy-Refusal-Subject` header.","uniqueKey":"refusal_subject","typeLabel":"string"},"denied_reason":{"type":"string","description":"Billing's policy branch for a partner-node spend denial - `no_funds` when the billed wallet is empty, `unspecified` when the call was refused without a funds reading saying so. Present only when `error_type` is `insufficient_credits` and the deployment reports wallet facts; absent otherwise. A machine-readable code, not display text: show `detail`, branch on this.","uniqueKey":"denied_reason","typeLabel":"string"},"billed_workspace":{"type":"object","description":"The wallet a refused call would have charged, on `RouterErrorResponse.billed_workspace`. Answers \"which wallet is empty?\" - it is not necessarily the workspace the caller's UI currently has selected, and a team member's personal credential names their personal wallet here even while a funded team is open. Present only alongside `denied_reason`.","properties":{"type":{"type":"string","description":"`personal` or `team`. An open string: treat any other value as personal.","isRequired":true,"uniqueKey":"billed_workspace.type","typeLabel":"string"},"id":{"type":"string","description":"The Cloud workspace id. Absent on the legacy rail.","uniqueKey":"billed_workspace.id","typeLabel":"string"},"rail":{"type":"string","description":"`legacy` when the call bills the caller's pre-workspace Metronome customer rather than a Cloud workspace; that customer has no workspace id. Absent for a Cloud workspace.","uniqueKey":"billed_workspace.rail","typeLabel":"string"}},"required":["type"],"uniqueKey":"billed_workspace","typeLabel":"object"},"credential_kind":{"type":"string","description":"How the refused request authenticated - `personal_api_key`, `team_api_key`, `personal_session` or `team_session`. Answers \"which credential do I switch to bill the other wallet?\". It is not a permission and grants nothing. Present only alongside `denied_reason`.","uniqueKey":"credential_kind","typeLabel":"string"}},"required":["detail","error_type"],"uniqueKey":"","typeLabel":"object"},"examples":{"Example":{"title":"Example","value":{"detail":"\u003cstring>","error_type":"invalid_input","upstream_detail":"\u003cstring>","refusal_subject":"\u003cstring>","denied_reason":"\u003cstring>","billed_workspace":{"type":"\u003cstring>","id":"\u003cstring>","rail":"\u003cstring>"},"credential_kind":"\u003cstring>"}}},"exampleType":"generated"}},"exampleType":"generated"},"108a7ca4-76b1-424a-8ae9-44203589422b":{"description":"A Router request-level failure - the request never reached the model, or failed for a reason the model itself did not report. The body is `RouterErrorResponse` and the bucket is repeated on `X-Comfy-Error-Type`.","headers":{"X-Comfy-Error-Type":{"description":"Coarse, machine-readable bucket for the failure, set by Router on every error response. It carries the same value as `RouterErrorResponse.error_type`, and on the `422` it is the only machine-readable bucket, because that body is the FastAPI `detail[]` shape and has no `error_type` field of its own. A client can therefore branch on this header alone, before deciding which of the two Router error bodies it received.","required":true,"schema":{"type":"string","description":"Coarse, machine-readable bucket for a Router failure, mirrored on the `X-Comfy-Error-Type` response header so a caller can branch without parsing the body. The set is closed at twenty values: the six request-level buckets `invalid_input`, `content_policy_violation`, `provider_error`, `provider_timeout`, `insufficient_credits` and `model_not_found`, plus the transport-level `unauthorized`, `forbidden`, `concurrency_limit_exceeded`, `client_disconnected`, `internal_error`, `deadline_exceeded`, `not_enabled`, `service_unavailable`, `rate_limited`, `cancelled`, `queue_timeout`, `request_not_found`, `queue_backlog_full` and `result_expired`. Closed describes the set as documented today, not a bound that holds forever: the set is expected to grow, which is why this is deliberately a plain string and not an `enum`, so a client must treat an unrecognised value as `internal_error` rather than switch exhaustively over the list above and break on the next addition.","example":"invalid_input","x-comfy-error-types":[{"value":"invalid_input","tier":"request","meaning":"The request was rejected before it reached the model - a malformed body, a malformed or expired pagination cursor, an input the model's own schema does not accept, or an `Idempotency-Key` that cannot serve this request (already used for a different request - the method, the path and query, or the body differ - or already consumed by a call whose response cannot be replayed). Sent with `409` in the key cases and with `400`/`422` in the others; the status says which, and the key cases are the ones answered by using a new key rather than by editing the request."},{"value":"content_policy_violation","tier":"request","meaning":"The provider refused the request on content-policy grounds. The refusal is deterministic: re-sending the same input will be refused again."},{"value":"provider_error","tier":"request","meaning":"The partner provider reported a failure of its own, or returned a response Router could not interpret as a result."},{"value":"provider_timeout","tier":"request","meaning":"The partner provider did not answer within its deadline. This bucket is the provider timing out and never Router's own server deadline, which is reported as `deadline_exceeded` - the two share `504` and are separated because they name different causes: this one says the partner failed, that one says Comfy stopped holding the connection."},{"value":"insufficient_credits","tier":"request","meaning":"The calling workspace does not have enough credits to run the model."},{"value":"model_not_found","tier":"request","meaning":"The `{provider}/{model}` ID names no model Router can run: an unknown provider, an unenrolled id, one the catalog has retired past its sunset date, or a catalogued ID the provider does not currently serve for Comfy. A retired id's `detail` reads `\u003cid> was retired on \u003cYYYY-MM-DD>; use \u003csuccessor>` when a successor is recorded and not withheld, or just `\u003cid> was retired on \u003cYYYY-MM-DD>` when it is not, instead of a suggestion list; the successor named for a retired id is always a live catalog ID you can re-point the call at, and a successor is dropped from `detail` either because the table records none, or because the recorded one is currently withheld behind an embargo the caller cannot see. A model whose sunset is still in the future is not withdrawn: it stays listed by `GET /v2/models` and stays runnable until the date, so a listing taken today remains the answer to what runs today. Otherwise `detail` carries up to three suggestions drawn from the models the caller is entitled to see, except for a catalogued ID the provider does not currently serve for Comfy, whose response carries no suggestions."},{"value":"unauthorized","tier":"transport","meaning":"The request carried no usable credential."},{"value":"forbidden","tier":"transport","meaning":"The credential is valid but is not entitled to this model or this operation."},{"value":"concurrency_limit_exceeded","tier":"transport","meaning":"The workspace already has as many calls in flight as it is allowed; retry once one of them finishes. It carries one further condition on the run route, on a `409` rather than the `429` above: another call is already in flight for the `Idempotency-Key` this request presented. Re-send the same key after `Retry-After` seconds to collect that call's result."},{"value":"client_disconnected","tier":"transport","meaning":"The caller closed the connection before Router could return a result. It is logged rather than delivered - there is no socket left to write it to - and it is an attribution, not a billing outcome: a provider generation that completed is billed regardless of whether the caller received the response."},{"value":"internal_error","tier":"transport","meaning":"Router itself failed. It is also the value a client should treat any unrecognized bucket as, so a later addition to the set does not break a client generated before it."},{"value":"deadline_exceeded","tier":"transport","meaning":"Comfy stopped holding the connection at its own configured bound before an answer arrived. It shares `504` with `provider_timeout` and the pair says which side ran out of time; this one is Comfy's own bound, so nothing about the request was rejected and the same request may be retried. It says nothing about the charge: a provider generation that completed is billed regardless of whether the caller received the response. Retry it with the same `Idempotency-Key`: when the provider had already accepted the generation, the retry collects that generation rather than dispatching another, and a `Retry-After` on the `504` says when to ask."},{"value":"not_enabled","tier":"transport","meaning":"Comfy Router is not switched on for this caller yet. Nothing about the request is wrong and the model exists, which is why this is not `model_not_found`; it shares `403` with `forbidden` and is not the same thing, because `forbidden` is an entitlement decision about the caller while this is a state of the rollout. It is terminal: do not retry, and do not treat it as an outage. The one exception to \"about the caller\" is the queued submit, which also answers `not_enabled` for a model whose partner answers a generation directly as bytes: that model cannot yet be queued, so it is the model and not the caller that is refused, nothing is queued or charged, and the synchronous route `POST /v2/models/{provider}/{model}` runs it instead."},{"value":"service_unavailable","tier":"transport","meaning":"A service Comfy Router depends on is temporarily unavailable and the caller did nothing wrong. Retry it with backoff: it is the one bucket here whose condition clears on its own, without the caller changing the request and without a concurrency slot freeing, which is what distinguishes it from the other retryable answers (`concurrency_limit_exceeded`, `deadline_exceeded`). It is separate from `internal_error` - which is a `500` and means Router itself failed - so a client can tell \"come back shortly\" from \"this call is not going to work\"."},{"value":"rate_limited","tier":"transport","meaning":"The caller has spent an allowance measured over a window and must wait for that window to roll. It shares `429` with `concurrency_limit_exceeded` and is not the same thing: that one clears the moment one of the caller's own in-flight calls finishes, so retrying in seconds is right, whereas nothing the caller does drains this one early. `detail` names the window, and `Retry-After` the seconds to wait."},{"value":"cancelled","tier":"transport","meaning":"A queued request was withdrawn — through the cancel route, or by an operator — before it produced a result; it is terminal, and it is not by itself a statement about the charge. Cancelling stops Comfy waiting and it does not always stop the partner working, so a request cancelled while it was still `IN_QUEUE` was never dispatched and cannot be charged, whereas one cancelled after it was admitted may still be charged — a partner generation that completes is charged whether or not anyone collected it, which is why the cancel route calls the ask a request rather than a guarantee. It is not `client_disconnected`: that one says nobody is listening any more while a generation may still be running and billable, whereas this says the request itself was withdrawn. A caller polling the status read sees `200` with this in the body, because the request ended and so the read succeeded. Collecting the result of such a request answers `409` in Router's error envelope: that read also worked, and what it found is a request whose terminal state - the caller's own decision - leaves nothing to return. It is deliberately not `410`, which on that route means the result aged out of its retention window, and not a `5xx`, which would report the caller's own cancellation as a Router fault and read to a polling client as worth retrying."},{"value":"queue_timeout","tier":"transport","meaning":"A queued request waited past its queue timeout without ever being admitted. Terminal, unbilled, and it never took a concurrency slot — the job never reached a provider. Deliberately not `deadline_exceeded`, which is the synchronous route's connection bound: a `deadline_exceeded` generation may be running and billable, whereas this one provably never started. It is returned under `504`, which it shares with `provider_timeout` and `deadline_exceeded` because a status can only say that a clock ran out; which clock - the partner's, Comfy's connection bound, or the queue's admission bound - is what `error_type` carries. The request itself is terminal, so submit a new one rather than re-reading this one."},{"value":"request_not_found","tier":"transport","meaning":"The `request_id` names no request of the caller's under this model. It is the second of the two conditions the queued reads' `404` covers; the first is the `{provider}/{model}` ID resolving to no partner model, which is `model_not_found` and carries fuzzy model suggestions. It also covers the right-id / wrong-model URL the path shape refuses, and it is deliberately indistinguishable from a request in another workspace, so a probe with a guessed id learns nothing. A request that has merely aged out of its retention window is `410`, not this."},{"value":"queue_backlog_full","tier":"transport","meaning":"The caller already has too many queued requests waiting to run, so this submit was refused. It shares `429` with `concurrency_limit_exceeded` and is not the same thing: that one is the synchronous route's answer for too many calls in flight at once, whereas the queue accepts a submit at that limit and parks it, and this bucket is the separate bound on how many a caller may leave waiting so that parking cannot mean enqueuing without end. It clears as the caller's own queued requests finish, so retry once some of them complete."},{"value":"result_expired","tier":"transport","meaning":"The request existed and finished, but its result is no longer stored, so the collect has nothing to return. It is returned under `410` and is permanent for that id: re-reading will answer the same way, so do not retry it. It is deliberately not `request_not_found`, which would tell you the id was never valid and invite re-submitting a generation that has already run. Running the model again means submitting a new request. For a workspace under a zero-data-retention agreement, a queued request's result is not kept after it is delivered: it is removed shortly after the first collect, and an uncollected result is removed after a grace period once the request finishes, so store the result on your side when you first collect it."}]}},"X-Comfy-Request-Id":{"description":"Server-generated identifier for this call, present on every Router response - success, 4xx and 5xx alike, because an error response is exactly when a user needs an id to quote in a support request. The same value is written into the call's usage/audit event, which is what lets a complaint about a charge be joined to the charge itself instead of searched for by timestamp.","required":true,"schema":{"type":"string","format":"uuid","example":"6f1a1a6e-6a53-4a5f-9d3a-2b3b0a1f9c21"}}},"content":{"application/json":{"schema":{"type":"object","description":"Router's request-level error body: what is returned when the request never reached the model, or failed for a reason the model itself did not report - auth, quota, an unknown model ID, or provider transport. A model-level validation failure has its own shape, `RouterValidationErrorResponse`, because flattening a FastAPI `detail[]` array into this `detail` string would destroy the per-field granularity an SDK branches on.","properties":{"detail":{"type":"string","description":"Human-readable description of the failure, safe to surface to an end user. Not machine-parsed - branch on `error_type` instead. For `model_not_found` on a retired model, `detail` reads `\u003cid> was retired on \u003cYYYY-MM-DD>; use \u003csuccessor>` when a successor is recorded and visible to the caller, or just `\u003cid> was retired on \u003cYYYY-MM-DD>` when it is not, instead of the usual suggestion list. A successor named here is always a live catalog ID the call can be re-pointed at. A model whose sunset date is still in the future is not retired: it stays listed by `GET /v2/models` and stays runnable until that date. Like the rest of `detail`, this retirement wording is for display and carries no compatibility guarantee.","isRequired":true,"uniqueKey":"detail","typeLabel":"string"},"error_type":{"type":"string","description":"Coarse, machine-readable bucket for a Router failure, mirrored on the `X-Comfy-Error-Type` response header so a caller can branch without parsing the body. The set is closed at twenty values: the six request-level buckets `invalid_input`, `content_policy_violation`, `provider_error`, `provider_timeout`, `insufficient_credits` and `model_not_found`, plus the transport-level `unauthorized`, `forbidden`, `concurrency_limit_exceeded`, `client_disconnected`, `internal_error`, `deadline_exceeded`, `not_enabled`, `service_unavailable`, `rate_limited`, `cancelled`, `queue_timeout`, `request_not_found`, `queue_backlog_full` and `result_expired`. Closed describes the set as documented today, not a bound that holds forever: the set is expected to grow, which is why this is deliberately a plain string and not an `enum`, so a client must treat an unrecognised value as `internal_error` rather than switch exhaustively over the list above and break on the next addition.","example":"invalid_input","x-comfy-error-types":[{"value":"invalid_input","tier":"request","meaning":"The request was rejected before it reached the model - a malformed body, a malformed or expired pagination cursor, an input the model's own schema does not accept, or an `Idempotency-Key` that cannot serve this request (already used for a different request - the method, the path and query, or the body differ - or already consumed by a call whose response cannot be replayed). Sent with `409` in the key cases and with `400`/`422` in the others; the status says which, and the key cases are the ones answered by using a new key rather than by editing the request."},{"value":"content_policy_violation","tier":"request","meaning":"The provider refused the request on content-policy grounds. The refusal is deterministic: re-sending the same input will be refused again."},{"value":"provider_error","tier":"request","meaning":"The partner provider reported a failure of its own, or returned a response Router could not interpret as a result."},{"value":"provider_timeout","tier":"request","meaning":"The partner provider did not answer within its deadline. This bucket is the provider timing out and never Router's own server deadline, which is reported as `deadline_exceeded` - the two share `504` and are separated because they name different causes: this one says the partner failed, that one says Comfy stopped holding the connection."},{"value":"insufficient_credits","tier":"request","meaning":"The calling workspace does not have enough credits to run the model."},{"value":"model_not_found","tier":"request","meaning":"The `{provider}/{model}` ID names no model Router can run: an unknown provider, an unenrolled id, one the catalog has retired past its sunset date, or a catalogued ID the provider does not currently serve for Comfy. A retired id's `detail` reads `\u003cid> was retired on \u003cYYYY-MM-DD>; use \u003csuccessor>` when a successor is recorded and not withheld, or just `\u003cid> was retired on \u003cYYYY-MM-DD>` when it is not, instead of a suggestion list; the successor named for a retired id is always a live catalog ID you can re-point the call at, and a successor is dropped from `detail` either because the table records none, or because the recorded one is currently withheld behind an embargo the caller cannot see. A model whose sunset is still in the future is not withdrawn: it stays listed by `GET /v2/models` and stays runnable until the date, so a listing taken today remains the answer to what runs today. Otherwise `detail` carries up to three suggestions drawn from the models the caller is entitled to see, except for a catalogued ID the provider does not currently serve for Comfy, whose response carries no suggestions."},{"value":"unauthorized","tier":"transport","meaning":"The request carried no usable credential."},{"value":"forbidden","tier":"transport","meaning":"The credential is valid but is not entitled to this model or this operation."},{"value":"concurrency_limit_exceeded","tier":"transport","meaning":"The workspace already has as many calls in flight as it is allowed; retry once one of them finishes. It carries one further condition on the run route, on a `409` rather than the `429` above: another call is already in flight for the `Idempotency-Key` this request presented. Re-send the same key after `Retry-After` seconds to collect that call's result."},{"value":"client_disconnected","tier":"transport","meaning":"The caller closed the connection before Router could return a result. It is logged rather than delivered - there is no socket left to write it to - and it is an attribution, not a billing outcome: a provider generation that completed is billed regardless of whether the caller received the response."},{"value":"internal_error","tier":"transport","meaning":"Router itself failed. It is also the value a client should treat any unrecognized bucket as, so a later addition to the set does not break a client generated before it."},{"value":"deadline_exceeded","tier":"transport","meaning":"Comfy stopped holding the connection at its own configured bound before an answer arrived. It shares `504` with `provider_timeout` and the pair says which side ran out of time; this one is Comfy's own bound, so nothing about the request was rejected and the same request may be retried. It says nothing about the charge: a provider generation that completed is billed regardless of whether the caller received the response. Retry it with the same `Idempotency-Key`: when the provider had already accepted the generation, the retry collects that generation rather than dispatching another, and a `Retry-After` on the `504` says when to ask."},{"value":"not_enabled","tier":"transport","meaning":"Comfy Router is not switched on for this caller yet. Nothing about the request is wrong and the model exists, which is why this is not `model_not_found`; it shares `403` with `forbidden` and is not the same thing, because `forbidden` is an entitlement decision about the caller while this is a state of the rollout. It is terminal: do not retry, and do not treat it as an outage. The one exception to \"about the caller\" is the queued submit, which also answers `not_enabled` for a model whose partner answers a generation directly as bytes: that model cannot yet be queued, so it is the model and not the caller that is refused, nothing is queued or charged, and the synchronous route `POST /v2/models/{provider}/{model}` runs it instead."},{"value":"service_unavailable","tier":"transport","meaning":"A service Comfy Router depends on is temporarily unavailable and the caller did nothing wrong. Retry it with backoff: it is the one bucket here whose condition clears on its own, without the caller changing the request and without a concurrency slot freeing, which is what distinguishes it from the other retryable answers (`concurrency_limit_exceeded`, `deadline_exceeded`). It is separate from `internal_error` - which is a `500` and means Router itself failed - so a client can tell \"come back shortly\" from \"this call is not going to work\"."},{"value":"rate_limited","tier":"transport","meaning":"The caller has spent an allowance measured over a window and must wait for that window to roll. It shares `429` with `concurrency_limit_exceeded` and is not the same thing: that one clears the moment one of the caller's own in-flight calls finishes, so retrying in seconds is right, whereas nothing the caller does drains this one early. `detail` names the window, and `Retry-After` the seconds to wait."},{"value":"cancelled","tier":"transport","meaning":"A queued request was withdrawn — through the cancel route, or by an operator — before it produced a result; it is terminal, and it is not by itself a statement about the charge. Cancelling stops Comfy waiting and it does not always stop the partner working, so a request cancelled while it was still `IN_QUEUE` was never dispatched and cannot be charged, whereas one cancelled after it was admitted may still be charged — a partner generation that completes is charged whether or not anyone collected it, which is why the cancel route calls the ask a request rather than a guarantee. It is not `client_disconnected`: that one says nobody is listening any more while a generation may still be running and billable, whereas this says the request itself was withdrawn. A caller polling the status read sees `200` with this in the body, because the request ended and so the read succeeded. Collecting the result of such a request answers `409` in Router's error envelope: that read also worked, and what it found is a request whose terminal state - the caller's own decision - leaves nothing to return. It is deliberately not `410`, which on that route means the result aged out of its retention window, and not a `5xx`, which would report the caller's own cancellation as a Router fault and read to a polling client as worth retrying."},{"value":"queue_timeout","tier":"transport","meaning":"A queued request waited past its queue timeout without ever being admitted. Terminal, unbilled, and it never took a concurrency slot — the job never reached a provider. Deliberately not `deadline_exceeded`, which is the synchronous route's connection bound: a `deadline_exceeded` generation may be running and billable, whereas this one provably never started. It is returned under `504`, which it shares with `provider_timeout` and `deadline_exceeded` because a status can only say that a clock ran out; which clock - the partner's, Comfy's connection bound, or the queue's admission bound - is what `error_type` carries. The request itself is terminal, so submit a new one rather than re-reading this one."},{"value":"request_not_found","tier":"transport","meaning":"The `request_id` names no request of the caller's under this model. It is the second of the two conditions the queued reads' `404` covers; the first is the `{provider}/{model}` ID resolving to no partner model, which is `model_not_found` and carries fuzzy model suggestions. It also covers the right-id / wrong-model URL the path shape refuses, and it is deliberately indistinguishable from a request in another workspace, so a probe with a guessed id learns nothing. A request that has merely aged out of its retention window is `410`, not this."},{"value":"queue_backlog_full","tier":"transport","meaning":"The caller already has too many queued requests waiting to run, so this submit was refused. It shares `429` with `concurrency_limit_exceeded` and is not the same thing: that one is the synchronous route's answer for too many calls in flight at once, whereas the queue accepts a submit at that limit and parks it, and this bucket is the separate bound on how many a caller may leave waiting so that parking cannot mean enqueuing without end. It clears as the caller's own queued requests finish, so retry once some of them complete."},{"value":"result_expired","tier":"transport","meaning":"The request existed and finished, but its result is no longer stored, so the collect has nothing to return. It is returned under `410` and is permanent for that id: re-reading will answer the same way, so do not retry it. It is deliberately not `request_not_found`, which would tell you the id was never valid and invite re-submitting a generation that has already run. Running the model again means submitting a new request. For a workspace under a zero-data-retention agreement, a queued request's result is not kept after it is delivered: it is removed shortly after the first collect, and an uncollected result is removed after a grace period once the request finishes, so store the result on your side when you first collect it."}],"isRequired":true,"uniqueKey":"error_type","typeLabel":"string"},"upstream_detail":{"type":"string","description":"A bounded, sanitized reason the model provider gave for rejecting the request, present only when `error_type` is `invalid_input` and `X-Comfy-Upstream-Status` is a provider `4xx` or `2xx` - i.e. the provider refused the request as malformed and said why. Usually that status is a `4xx`; it is a `2xx` for a provider that reports a rejected generation inside a success envelope (a BytePlus failed-task poll is HTTP `200` with the reason in its body). Absent on every other failure, including provider `5xx`, transport failures, content-policy refusals and any refusal Router raised about itself. It mirrors the `X-Comfy-Upstream-Detail` header. The queued collect (`GET /v2/models/{provider}/{model}/requests/{request_id}`) of a run that ended `invalid_input` carries the same reason in this field on its first collect, which then deletes it from the request: a later collect normally answers the same `error_type` and `detail` without it, so read it from the first collect. That read sends neither header.","uniqueKey":"upstream_detail","typeLabel":"string"},"refusal_subject":{"type":"string","description":"Which input or output a content-policy refusal was about, as a Router-level closed vocabulary: `input`, `output`, `input_text`, `input_image`, `input_video`, `input_audio`, `output_text`, `output_image`, `output_video`, `output_audio`. The bare `input` / `output` values name the side when the provider did not name a modality. Present only when `error_type` is `content_policy_violation` and the provider named the refused subject with a machine-readable code; absent otherwise. Never provider text. Named today for BytePlus, Runway, BFL, Gemini, Veo, Vertex, xAI and Wan refusals, and for the MiniMax Router's Nano Banana legs' Gemini refusals; a provider whose refusal does not say which side it was about leaves it absent. It mirrors the `X-Comfy-Refusal-Subject` header.","uniqueKey":"refusal_subject","typeLabel":"string"},"denied_reason":{"type":"string","description":"Billing's policy branch for a partner-node spend denial - `no_funds` when the billed wallet is empty, `unspecified` when the call was refused without a funds reading saying so. Present only when `error_type` is `insufficient_credits` and the deployment reports wallet facts; absent otherwise. A machine-readable code, not display text: show `detail`, branch on this.","uniqueKey":"denied_reason","typeLabel":"string"},"billed_workspace":{"type":"object","description":"The wallet a refused call would have charged, on `RouterErrorResponse.billed_workspace`. Answers \"which wallet is empty?\" - it is not necessarily the workspace the caller's UI currently has selected, and a team member's personal credential names their personal wallet here even while a funded team is open. Present only alongside `denied_reason`.","properties":{"type":{"type":"string","description":"`personal` or `team`. An open string: treat any other value as personal.","isRequired":true,"uniqueKey":"billed_workspace.type","typeLabel":"string"},"id":{"type":"string","description":"The Cloud workspace id. Absent on the legacy rail.","uniqueKey":"billed_workspace.id","typeLabel":"string"},"rail":{"type":"string","description":"`legacy` when the call bills the caller's pre-workspace Metronome customer rather than a Cloud workspace; that customer has no workspace id. Absent for a Cloud workspace.","uniqueKey":"billed_workspace.rail","typeLabel":"string"}},"required":["type"],"uniqueKey":"billed_workspace","typeLabel":"object"},"credential_kind":{"type":"string","description":"How the refused request authenticated - `personal_api_key`, `team_api_key`, `personal_session` or `team_session`. Answers \"which credential do I switch to bill the other wallet?\". It is not a permission and grants nothing. Present only alongside `denied_reason`.","uniqueKey":"credential_kind","typeLabel":"string"}},"required":["detail","error_type"],"uniqueKey":"","typeLabel":"object"},"examples":{"Example":{"title":"Example","value":{"detail":"\u003cstring>","error_type":"invalid_input","upstream_detail":"\u003cstring>","refusal_subject":"\u003cstring>","denied_reason":"\u003cstring>","billed_workspace":{"type":"\u003cstring>","id":"\u003cstring>","rail":"\u003cstring>"},"credential_kind":"\u003cstring>"}}},"exampleType":"generated"}},"exampleType":"generated"},"5a95d66a-a988-4374-982b-8431b52c5c06":{"description":"A Router request-level failure - the request never reached the model, or failed for a reason the model itself did not report. The body is `RouterErrorResponse` and the bucket is repeated on `X-Comfy-Error-Type`.","headers":{"X-Comfy-Error-Type":{"description":"Coarse, machine-readable bucket for the failure, set by Router on every error response. It carries the same value as `RouterErrorResponse.error_type`, and on the `422` it is the only machine-readable bucket, because that body is the FastAPI `detail[]` shape and has no `error_type` field of its own. A client can therefore branch on this header alone, before deciding which of the two Router error bodies it received.","required":true,"schema":{"type":"string","description":"Coarse, machine-readable bucket for a Router failure, mirrored on the `X-Comfy-Error-Type` response header so a caller can branch without parsing the body. The set is closed at twenty values: the six request-level buckets `invalid_input`, `content_policy_violation`, `provider_error`, `provider_timeout`, `insufficient_credits` and `model_not_found`, plus the transport-level `unauthorized`, `forbidden`, `concurrency_limit_exceeded`, `client_disconnected`, `internal_error`, `deadline_exceeded`, `not_enabled`, `service_unavailable`, `rate_limited`, `cancelled`, `queue_timeout`, `request_not_found`, `queue_backlog_full` and `result_expired`. Closed describes the set as documented today, not a bound that holds forever: the set is expected to grow, which is why this is deliberately a plain string and not an `enum`, so a client must treat an unrecognised value as `internal_error` rather than switch exhaustively over the list above and break on the next addition.","example":"invalid_input","x-comfy-error-types":[{"value":"invalid_input","tier":"request","meaning":"The request was rejected before it reached the model - a malformed body, a malformed or expired pagination cursor, an input the model's own schema does not accept, or an `Idempotency-Key` that cannot serve this request (already used for a different request - the method, the path and query, or the body differ - or already consumed by a call whose response cannot be replayed). Sent with `409` in the key cases and with `400`/`422` in the others; the status says which, and the key cases are the ones answered by using a new key rather than by editing the request."},{"value":"content_policy_violation","tier":"request","meaning":"The provider refused the request on content-policy grounds. The refusal is deterministic: re-sending the same input will be refused again."},{"value":"provider_error","tier":"request","meaning":"The partner provider reported a failure of its own, or returned a response Router could not interpret as a result."},{"value":"provider_timeout","tier":"request","meaning":"The partner provider did not answer within its deadline. This bucket is the provider timing out and never Router's own server deadline, which is reported as `deadline_exceeded` - the two share `504` and are separated because they name different causes: this one says the partner failed, that one says Comfy stopped holding the connection."},{"value":"insufficient_credits","tier":"request","meaning":"The calling workspace does not have enough credits to run the model."},{"value":"model_not_found","tier":"request","meaning":"The `{provider}/{model}` ID names no model Router can run: an unknown provider, an unenrolled id, one the catalog has retired past its sunset date, or a catalogued ID the provider does not currently serve for Comfy. A retired id's `detail` reads `\u003cid> was retired on \u003cYYYY-MM-DD>; use \u003csuccessor>` when a successor is recorded and not withheld, or just `\u003cid> was retired on \u003cYYYY-MM-DD>` when it is not, instead of a suggestion list; the successor named for a retired id is always a live catalog ID you can re-point the call at, and a successor is dropped from `detail` either because the table records none, or because the recorded one is currently withheld behind an embargo the caller cannot see. A model whose sunset is still in the future is not withdrawn: it stays listed by `GET /v2/models` and stays runnable until the date, so a listing taken today remains the answer to what runs today. Otherwise `detail` carries up to three suggestions drawn from the models the caller is entitled to see, except for a catalogued ID the provider does not currently serve for Comfy, whose response carries no suggestions."},{"value":"unauthorized","tier":"transport","meaning":"The request carried no usable credential."},{"value":"forbidden","tier":"transport","meaning":"The credential is valid but is not entitled to this model or this operation."},{"value":"concurrency_limit_exceeded","tier":"transport","meaning":"The workspace already has as many calls in flight as it is allowed; retry once one of them finishes. It carries one further condition on the run route, on a `409` rather than the `429` above: another call is already in flight for the `Idempotency-Key` this request presented. Re-send the same key after `Retry-After` seconds to collect that call's result."},{"value":"client_disconnected","tier":"transport","meaning":"The caller closed the connection before Router could return a result. It is logged rather than delivered - there is no socket left to write it to - and it is an attribution, not a billing outcome: a provider generation that completed is billed regardless of whether the caller received the response."},{"value":"internal_error","tier":"transport","meaning":"Router itself failed. It is also the value a client should treat any unrecognized bucket as, so a later addition to the set does not break a client generated before it."},{"value":"deadline_exceeded","tier":"transport","meaning":"Comfy stopped holding the connection at its own configured bound before an answer arrived. It shares `504` with `provider_timeout` and the pair says which side ran out of time; this one is Comfy's own bound, so nothing about the request was rejected and the same request may be retried. It says nothing about the charge: a provider generation that completed is billed regardless of whether the caller received the response. Retry it with the same `Idempotency-Key`: when the provider had already accepted the generation, the retry collects that generation rather than dispatching another, and a `Retry-After` on the `504` says when to ask."},{"value":"not_enabled","tier":"transport","meaning":"Comfy Router is not switched on for this caller yet. Nothing about the request is wrong and the model exists, which is why this is not `model_not_found`; it shares `403` with `forbidden` and is not the same thing, because `forbidden` is an entitlement decision about the caller while this is a state of the rollout. It is terminal: do not retry, and do not treat it as an outage. The one exception to \"about the caller\" is the queued submit, which also answers `not_enabled` for a model whose partner answers a generation directly as bytes: that model cannot yet be queued, so it is the model and not the caller that is refused, nothing is queued or charged, and the synchronous route `POST /v2/models/{provider}/{model}` runs it instead."},{"value":"service_unavailable","tier":"transport","meaning":"A service Comfy Router depends on is temporarily unavailable and the caller did nothing wrong. Retry it with backoff: it is the one bucket here whose condition clears on its own, without the caller changing the request and without a concurrency slot freeing, which is what distinguishes it from the other retryable answers (`concurrency_limit_exceeded`, `deadline_exceeded`). It is separate from `internal_error` - which is a `500` and means Router itself failed - so a client can tell \"come back shortly\" from \"this call is not going to work\"."},{"value":"rate_limited","tier":"transport","meaning":"The caller has spent an allowance measured over a window and must wait for that window to roll. It shares `429` with `concurrency_limit_exceeded` and is not the same thing: that one clears the moment one of the caller's own in-flight calls finishes, so retrying in seconds is right, whereas nothing the caller does drains this one early. `detail` names the window, and `Retry-After` the seconds to wait."},{"value":"cancelled","tier":"transport","meaning":"A queued request was withdrawn — through the cancel route, or by an operator — before it produced a result; it is terminal, and it is not by itself a statement about the charge. Cancelling stops Comfy waiting and it does not always stop the partner working, so a request cancelled while it was still `IN_QUEUE` was never dispatched and cannot be charged, whereas one cancelled after it was admitted may still be charged — a partner generation that completes is charged whether or not anyone collected it, which is why the cancel route calls the ask a request rather than a guarantee. It is not `client_disconnected`: that one says nobody is listening any more while a generation may still be running and billable, whereas this says the request itself was withdrawn. A caller polling the status read sees `200` with this in the body, because the request ended and so the read succeeded. Collecting the result of such a request answers `409` in Router's error envelope: that read also worked, and what it found is a request whose terminal state - the caller's own decision - leaves nothing to return. It is deliberately not `410`, which on that route means the result aged out of its retention window, and not a `5xx`, which would report the caller's own cancellation as a Router fault and read to a polling client as worth retrying."},{"value":"queue_timeout","tier":"transport","meaning":"A queued request waited past its queue timeout without ever being admitted. Terminal, unbilled, and it never took a concurrency slot — the job never reached a provider. Deliberately not `deadline_exceeded`, which is the synchronous route's connection bound: a `deadline_exceeded` generation may be running and billable, whereas this one provably never started. It is returned under `504`, which it shares with `provider_timeout` and `deadline_exceeded` because a status can only say that a clock ran out; which clock - the partner's, Comfy's connection bound, or the queue's admission bound - is what `error_type` carries. The request itself is terminal, so submit a new one rather than re-reading this one."},{"value":"request_not_found","tier":"transport","meaning":"The `request_id` names no request of the caller's under this model. It is the second of the two conditions the queued reads' `404` covers; the first is the `{provider}/{model}` ID resolving to no partner model, which is `model_not_found` and carries fuzzy model suggestions. It also covers the right-id / wrong-model URL the path shape refuses, and it is deliberately indistinguishable from a request in another workspace, so a probe with a guessed id learns nothing. A request that has merely aged out of its retention window is `410`, not this."},{"value":"queue_backlog_full","tier":"transport","meaning":"The caller already has too many queued requests waiting to run, so this submit was refused. It shares `429` with `concurrency_limit_exceeded` and is not the same thing: that one is the synchronous route's answer for too many calls in flight at once, whereas the queue accepts a submit at that limit and parks it, and this bucket is the separate bound on how many a caller may leave waiting so that parking cannot mean enqueuing without end. It clears as the caller's own queued requests finish, so retry once some of them complete."},{"value":"result_expired","tier":"transport","meaning":"The request existed and finished, but its result is no longer stored, so the collect has nothing to return. It is returned under `410` and is permanent for that id: re-reading will answer the same way, so do not retry it. It is deliberately not `request_not_found`, which would tell you the id was never valid and invite re-submitting a generation that has already run. Running the model again means submitting a new request. For a workspace under a zero-data-retention agreement, a queued request's result is not kept after it is delivered: it is removed shortly after the first collect, and an uncollected result is removed after a grace period once the request finishes, so store the result on your side when you first collect it."}]}},"X-Comfy-Request-Id":{"description":"Server-generated identifier for this call, present on every Router response - success, 4xx and 5xx alike, because an error response is exactly when a user needs an id to quote in a support request. The same value is written into the call's usage/audit event, which is what lets a complaint about a charge be joined to the charge itself instead of searched for by timestamp.","required":true,"schema":{"type":"string","format":"uuid","example":"6f1a1a6e-6a53-4a5f-9d3a-2b3b0a1f9c21"}}},"content":{"application/json":{"schema":{"type":"object","description":"Router's request-level error body: what is returned when the request never reached the model, or failed for a reason the model itself did not report - auth, quota, an unknown model ID, or provider transport. A model-level validation failure has its own shape, `RouterValidationErrorResponse`, because flattening a FastAPI `detail[]` array into this `detail` string would destroy the per-field granularity an SDK branches on.","properties":{"detail":{"type":"string","description":"Human-readable description of the failure, safe to surface to an end user. Not machine-parsed - branch on `error_type` instead. For `model_not_found` on a retired model, `detail` reads `\u003cid> was retired on \u003cYYYY-MM-DD>; use \u003csuccessor>` when a successor is recorded and visible to the caller, or just `\u003cid> was retired on \u003cYYYY-MM-DD>` when it is not, instead of the usual suggestion list. A successor named here is always a live catalog ID the call can be re-pointed at. A model whose sunset date is still in the future is not retired: it stays listed by `GET /v2/models` and stays runnable until that date. Like the rest of `detail`, this retirement wording is for display and carries no compatibility guarantee.","isRequired":true,"uniqueKey":"detail","typeLabel":"string"},"error_type":{"type":"string","description":"Coarse, machine-readable bucket for a Router failure, mirrored on the `X-Comfy-Error-Type` response header so a caller can branch without parsing the body. The set is closed at twenty values: the six request-level buckets `invalid_input`, `content_policy_violation`, `provider_error`, `provider_timeout`, `insufficient_credits` and `model_not_found`, plus the transport-level `unauthorized`, `forbidden`, `concurrency_limit_exceeded`, `client_disconnected`, `internal_error`, `deadline_exceeded`, `not_enabled`, `service_unavailable`, `rate_limited`, `cancelled`, `queue_timeout`, `request_not_found`, `queue_backlog_full` and `result_expired`. Closed describes the set as documented today, not a bound that holds forever: the set is expected to grow, which is why this is deliberately a plain string and not an `enum`, so a client must treat an unrecognised value as `internal_error` rather than switch exhaustively over the list above and break on the next addition.","example":"invalid_input","x-comfy-error-types":[{"value":"invalid_input","tier":"request","meaning":"The request was rejected before it reached the model - a malformed body, a malformed or expired pagination cursor, an input the model's own schema does not accept, or an `Idempotency-Key` that cannot serve this request (already used for a different request - the method, the path and query, or the body differ - or already consumed by a call whose response cannot be replayed). Sent with `409` in the key cases and with `400`/`422` in the others; the status says which, and the key cases are the ones answered by using a new key rather than by editing the request."},{"value":"content_policy_violation","tier":"request","meaning":"The provider refused the request on content-policy grounds. The refusal is deterministic: re-sending the same input will be refused again."},{"value":"provider_error","tier":"request","meaning":"The partner provider reported a failure of its own, or returned a response Router could not interpret as a result."},{"value":"provider_timeout","tier":"request","meaning":"The partner provider did not answer within its deadline. This bucket is the provider timing out and never Router's own server deadline, which is reported as `deadline_exceeded` - the two share `504` and are separated because they name different causes: this one says the partner failed, that one says Comfy stopped holding the connection."},{"value":"insufficient_credits","tier":"request","meaning":"The calling workspace does not have enough credits to run the model."},{"value":"model_not_found","tier":"request","meaning":"The `{provider}/{model}` ID names no model Router can run: an unknown provider, an unenrolled id, one the catalog has retired past its sunset date, or a catalogued ID the provider does not currently serve for Comfy. A retired id's `detail` reads `\u003cid> was retired on \u003cYYYY-MM-DD>; use \u003csuccessor>` when a successor is recorded and not withheld, or just `\u003cid> was retired on \u003cYYYY-MM-DD>` when it is not, instead of a suggestion list; the successor named for a retired id is always a live catalog ID you can re-point the call at, and a successor is dropped from `detail` either because the table records none, or because the recorded one is currently withheld behind an embargo the caller cannot see. A model whose sunset is still in the future is not withdrawn: it stays listed by `GET /v2/models` and stays runnable until the date, so a listing taken today remains the answer to what runs today. Otherwise `detail` carries up to three suggestions drawn from the models the caller is entitled to see, except for a catalogued ID the provider does not currently serve for Comfy, whose response carries no suggestions."},{"value":"unauthorized","tier":"transport","meaning":"The request carried no usable credential."},{"value":"forbidden","tier":"transport","meaning":"The credential is valid but is not entitled to this model or this operation."},{"value":"concurrency_limit_exceeded","tier":"transport","meaning":"The workspace already has as many calls in flight as it is allowed; retry once one of them finishes. It carries one further condition on the run route, on a `409` rather than the `429` above: another call is already in flight for the `Idempotency-Key` this request presented. Re-send the same key after `Retry-After` seconds to collect that call's result."},{"value":"client_disconnected","tier":"transport","meaning":"The caller closed the connection before Router could return a result. It is logged rather than delivered - there is no socket left to write it to - and it is an attribution, not a billing outcome: a provider generation that completed is billed regardless of whether the caller received the response."},{"value":"internal_error","tier":"transport","meaning":"Router itself failed. It is also the value a client should treat any unrecognized bucket as, so a later addition to the set does not break a client generated before it."},{"value":"deadline_exceeded","tier":"transport","meaning":"Comfy stopped holding the connection at its own configured bound before an answer arrived. It shares `504` with `provider_timeout` and the pair says which side ran out of time; this one is Comfy's own bound, so nothing about the request was rejected and the same request may be retried. It says nothing about the charge: a provider generation that completed is billed regardless of whether the caller received the response. Retry it with the same `Idempotency-Key`: when the provider had already accepted the generation, the retry collects that generation rather than dispatching another, and a `Retry-After` on the `504` says when to ask."},{"value":"not_enabled","tier":"transport","meaning":"Comfy Router is not switched on for this caller yet. Nothing about the request is wrong and the model exists, which is why this is not `model_not_found`; it shares `403` with `forbidden` and is not the same thing, because `forbidden` is an entitlement decision about the caller while this is a state of the rollout. It is terminal: do not retry, and do not treat it as an outage. The one exception to \"about the caller\" is the queued submit, which also answers `not_enabled` for a model whose partner answers a generation directly as bytes: that model cannot yet be queued, so it is the model and not the caller that is refused, nothing is queued or charged, and the synchronous route `POST /v2/models/{provider}/{model}` runs it instead."},{"value":"service_unavailable","tier":"transport","meaning":"A service Comfy Router depends on is temporarily unavailable and the caller did nothing wrong. Retry it with backoff: it is the one bucket here whose condition clears on its own, without the caller changing the request and without a concurrency slot freeing, which is what distinguishes it from the other retryable answers (`concurrency_limit_exceeded`, `deadline_exceeded`). It is separate from `internal_error` - which is a `500` and means Router itself failed - so a client can tell \"come back shortly\" from \"this call is not going to work\"."},{"value":"rate_limited","tier":"transport","meaning":"The caller has spent an allowance measured over a window and must wait for that window to roll. It shares `429` with `concurrency_limit_exceeded` and is not the same thing: that one clears the moment one of the caller's own in-flight calls finishes, so retrying in seconds is right, whereas nothing the caller does drains this one early. `detail` names the window, and `Retry-After` the seconds to wait."},{"value":"cancelled","tier":"transport","meaning":"A queued request was withdrawn — through the cancel route, or by an operator — before it produced a result; it is terminal, and it is not by itself a statement about the charge. Cancelling stops Comfy waiting and it does not always stop the partner working, so a request cancelled while it was still `IN_QUEUE` was never dispatched and cannot be charged, whereas one cancelled after it was admitted may still be charged — a partner generation that completes is charged whether or not anyone collected it, which is why the cancel route calls the ask a request rather than a guarantee. It is not `client_disconnected`: that one says nobody is listening any more while a generation may still be running and billable, whereas this says the request itself was withdrawn. A caller polling the status read sees `200` with this in the body, because the request ended and so the read succeeded. Collecting the result of such a request answers `409` in Router's error envelope: that read also worked, and what it found is a request whose terminal state - the caller's own decision - leaves nothing to return. It is deliberately not `410`, which on that route means the result aged out of its retention window, and not a `5xx`, which would report the caller's own cancellation as a Router fault and read to a polling client as worth retrying."},{"value":"queue_timeout","tier":"transport","meaning":"A queued request waited past its queue timeout without ever being admitted. Terminal, unbilled, and it never took a concurrency slot — the job never reached a provider. Deliberately not `deadline_exceeded`, which is the synchronous route's connection bound: a `deadline_exceeded` generation may be running and billable, whereas this one provably never started. It is returned under `504`, which it shares with `provider_timeout` and `deadline_exceeded` because a status can only say that a clock ran out; which clock - the partner's, Comfy's connection bound, or the queue's admission bound - is what `error_type` carries. The request itself is terminal, so submit a new one rather than re-reading this one."},{"value":"request_not_found","tier":"transport","meaning":"The `request_id` names no request of the caller's under this model. It is the second of the two conditions the queued reads' `404` covers; the first is the `{provider}/{model}` ID resolving to no partner model, which is `model_not_found` and carries fuzzy model suggestions. It also covers the right-id / wrong-model URL the path shape refuses, and it is deliberately indistinguishable from a request in another workspace, so a probe with a guessed id learns nothing. A request that has merely aged out of its retention window is `410`, not this."},{"value":"queue_backlog_full","tier":"transport","meaning":"The caller already has too many queued requests waiting to run, so this submit was refused. It shares `429` with `concurrency_limit_exceeded` and is not the same thing: that one is the synchronous route's answer for too many calls in flight at once, whereas the queue accepts a submit at that limit and parks it, and this bucket is the separate bound on how many a caller may leave waiting so that parking cannot mean enqueuing without end. It clears as the caller's own queued requests finish, so retry once some of them complete."},{"value":"result_expired","tier":"transport","meaning":"The request existed and finished, but its result is no longer stored, so the collect has nothing to return. It is returned under `410` and is permanent for that id: re-reading will answer the same way, so do not retry it. It is deliberately not `request_not_found`, which would tell you the id was never valid and invite re-submitting a generation that has already run. Running the model again means submitting a new request. For a workspace under a zero-data-retention agreement, a queued request's result is not kept after it is delivered: it is removed shortly after the first collect, and an uncollected result is removed after a grace period once the request finishes, so store the result on your side when you first collect it."}],"isRequired":true,"uniqueKey":"error_type","typeLabel":"string"},"upstream_detail":{"type":"string","description":"A bounded, sanitized reason the model provider gave for rejecting the request, present only when `error_type` is `invalid_input` and `X-Comfy-Upstream-Status` is a provider `4xx` or `2xx` - i.e. the provider refused the request as malformed and said why. Usually that status is a `4xx`; it is a `2xx` for a provider that reports a rejected generation inside a success envelope (a BytePlus failed-task poll is HTTP `200` with the reason in its body). Absent on every other failure, including provider `5xx`, transport failures, content-policy refusals and any refusal Router raised about itself. It mirrors the `X-Comfy-Upstream-Detail` header. The queued collect (`GET /v2/models/{provider}/{model}/requests/{request_id}`) of a run that ended `invalid_input` carries the same reason in this field on its first collect, which then deletes it from the request: a later collect normally answers the same `error_type` and `detail` without it, so read it from the first collect. That read sends neither header.","uniqueKey":"upstream_detail","typeLabel":"string"},"refusal_subject":{"type":"string","description":"Which input or output a content-policy refusal was about, as a Router-level closed vocabulary: `input`, `output`, `input_text`, `input_image`, `input_video`, `input_audio`, `output_text`, `output_image`, `output_video`, `output_audio`. The bare `input` / `output` values name the side when the provider did not name a modality. Present only when `error_type` is `content_policy_violation` and the provider named the refused subject with a machine-readable code; absent otherwise. Never provider text. Named today for BytePlus, Runway, BFL, Gemini, Veo, Vertex, xAI and Wan refusals, and for the MiniMax Router's Nano Banana legs' Gemini refusals; a provider whose refusal does not say which side it was about leaves it absent. It mirrors the `X-Comfy-Refusal-Subject` header.","uniqueKey":"refusal_subject","typeLabel":"string"},"denied_reason":{"type":"string","description":"Billing's policy branch for a partner-node spend denial - `no_funds` when the billed wallet is empty, `unspecified` when the call was refused without a funds reading saying so. Present only when `error_type` is `insufficient_credits` and the deployment reports wallet facts; absent otherwise. A machine-readable code, not display text: show `detail`, branch on this.","uniqueKey":"denied_reason","typeLabel":"string"},"billed_workspace":{"type":"object","description":"The wallet a refused call would have charged, on `RouterErrorResponse.billed_workspace`. Answers \"which wallet is empty?\" - it is not necessarily the workspace the caller's UI currently has selected, and a team member's personal credential names their personal wallet here even while a funded team is open. Present only alongside `denied_reason`.","properties":{"type":{"type":"string","description":"`personal` or `team`. An open string: treat any other value as personal.","isRequired":true,"uniqueKey":"billed_workspace.type","typeLabel":"string"},"id":{"type":"string","description":"The Cloud workspace id. Absent on the legacy rail.","uniqueKey":"billed_workspace.id","typeLabel":"string"},"rail":{"type":"string","description":"`legacy` when the call bills the caller's pre-workspace Metronome customer rather than a Cloud workspace; that customer has no workspace id. Absent for a Cloud workspace.","uniqueKey":"billed_workspace.rail","typeLabel":"string"}},"required":["type"],"uniqueKey":"billed_workspace","typeLabel":"object"},"credential_kind":{"type":"string","description":"How the refused request authenticated - `personal_api_key`, `team_api_key`, `personal_session` or `team_session`. Answers \"which credential do I switch to bill the other wallet?\". It is not a permission and grants nothing. Present only alongside `denied_reason`.","uniqueKey":"credential_kind","typeLabel":"string"}},"required":["detail","error_type"],"uniqueKey":"","typeLabel":"object"},"examples":{"Example":{"title":"Example","value":{"detail":"\u003cstring>","error_type":"invalid_input","upstream_detail":"\u003cstring>","refusal_subject":"\u003cstring>","denied_reason":"\u003cstring>","billed_workspace":{"type":"\u003cstring>","id":"\u003cstring>","rail":"\u003cstring>"},"credential_kind":"\u003cstring>"}}},"exampleType":"generated"}},"exampleType":"generated"},"d150b00d-b13c-4f8c-a157-8aea0e407b73":{"description":"The caller has spent their per-caller request allowance, which refills continuously over a one-minute window, and the request was refused before Router did anything with it. The bucket is always `rate_limited`: wait the number of seconds in `Retry-After` before sending the next request. Nothing was charged, and a request sent sooner is refused again. The body is `RouterErrorResponse` and the bucket is repeated on `X-Comfy-Error-Type`.","headers":{"X-Comfy-Error-Type":{"description":"Coarse, machine-readable bucket for the failure, set by Router on every error response. It carries the same value as `RouterErrorResponse.error_type`, and on the `422` it is the only machine-readable bucket, because that body is the FastAPI `detail[]` shape and has no `error_type` field of its own. A client can therefore branch on this header alone, before deciding which of the two Router error bodies it received.","required":true,"schema":{"type":"string","description":"Coarse, machine-readable bucket for a Router failure, mirrored on the `X-Comfy-Error-Type` response header so a caller can branch without parsing the body. The set is closed at twenty values: the six request-level buckets `invalid_input`, `content_policy_violation`, `provider_error`, `provider_timeout`, `insufficient_credits` and `model_not_found`, plus the transport-level `unauthorized`, `forbidden`, `concurrency_limit_exceeded`, `client_disconnected`, `internal_error`, `deadline_exceeded`, `not_enabled`, `service_unavailable`, `rate_limited`, `cancelled`, `queue_timeout`, `request_not_found`, `queue_backlog_full` and `result_expired`. Closed describes the set as documented today, not a bound that holds forever: the set is expected to grow, which is why this is deliberately a plain string and not an `enum`, so a client must treat an unrecognised value as `internal_error` rather than switch exhaustively over the list above and break on the next addition.","example":"invalid_input","x-comfy-error-types":[{"value":"invalid_input","tier":"request","meaning":"The request was rejected before it reached the model - a malformed body, a malformed or expired pagination cursor, an input the model's own schema does not accept, or an `Idempotency-Key` that cannot serve this request (already used for a different request - the method, the path and query, or the body differ - or already consumed by a call whose response cannot be replayed). Sent with `409` in the key cases and with `400`/`422` in the others; the status says which, and the key cases are the ones answered by using a new key rather than by editing the request."},{"value":"content_policy_violation","tier":"request","meaning":"The provider refused the request on content-policy grounds. The refusal is deterministic: re-sending the same input will be refused again."},{"value":"provider_error","tier":"request","meaning":"The partner provider reported a failure of its own, or returned a response Router could not interpret as a result."},{"value":"provider_timeout","tier":"request","meaning":"The partner provider did not answer within its deadline. This bucket is the provider timing out and never Router's own server deadline, which is reported as `deadline_exceeded` - the two share `504` and are separated because they name different causes: this one says the partner failed, that one says Comfy stopped holding the connection."},{"value":"insufficient_credits","tier":"request","meaning":"The calling workspace does not have enough credits to run the model."},{"value":"model_not_found","tier":"request","meaning":"The `{provider}/{model}` ID names no model Router can run: an unknown provider, an unenrolled id, one the catalog has retired past its sunset date, or a catalogued ID the provider does not currently serve for Comfy. A retired id's `detail` reads `\u003cid> was retired on \u003cYYYY-MM-DD>; use \u003csuccessor>` when a successor is recorded and not withheld, or just `\u003cid> was retired on \u003cYYYY-MM-DD>` when it is not, instead of a suggestion list; the successor named for a retired id is always a live catalog ID you can re-point the call at, and a successor is dropped from `detail` either because the table records none, or because the recorded one is currently withheld behind an embargo the caller cannot see. A model whose sunset is still in the future is not withdrawn: it stays listed by `GET /v2/models` and stays runnable until the date, so a listing taken today remains the answer to what runs today. Otherwise `detail` carries up to three suggestions drawn from the models the caller is entitled to see, except for a catalogued ID the provider does not currently serve for Comfy, whose response carries no suggestions."},{"value":"unauthorized","tier":"transport","meaning":"The request carried no usable credential."},{"value":"forbidden","tier":"transport","meaning":"The credential is valid but is not entitled to this model or this operation."},{"value":"concurrency_limit_exceeded","tier":"transport","meaning":"The workspace already has as many calls in flight as it is allowed; retry once one of them finishes. It carries one further condition on the run route, on a `409` rather than the `429` above: another call is already in flight for the `Idempotency-Key` this request presented. Re-send the same key after `Retry-After` seconds to collect that call's result."},{"value":"client_disconnected","tier":"transport","meaning":"The caller closed the connection before Router could return a result. It is logged rather than delivered - there is no socket left to write it to - and it is an attribution, not a billing outcome: a provider generation that completed is billed regardless of whether the caller received the response."},{"value":"internal_error","tier":"transport","meaning":"Router itself failed. It is also the value a client should treat any unrecognized bucket as, so a later addition to the set does not break a client generated before it."},{"value":"deadline_exceeded","tier":"transport","meaning":"Comfy stopped holding the connection at its own configured bound before an answer arrived. It shares `504` with `provider_timeout` and the pair says which side ran out of time; this one is Comfy's own bound, so nothing about the request was rejected and the same request may be retried. It says nothing about the charge: a provider generation that completed is billed regardless of whether the caller received the response. Retry it with the same `Idempotency-Key`: when the provider had already accepted the generation, the retry collects that generation rather than dispatching another, and a `Retry-After` on the `504` says when to ask."},{"value":"not_enabled","tier":"transport","meaning":"Comfy Router is not switched on for this caller yet. Nothing about the request is wrong and the model exists, which is why this is not `model_not_found`; it shares `403` with `forbidden` and is not the same thing, because `forbidden` is an entitlement decision about the caller while this is a state of the rollout. It is terminal: do not retry, and do not treat it as an outage. The one exception to \"about the caller\" is the queued submit, which also answers `not_enabled` for a model whose partner answers a generation directly as bytes: that model cannot yet be queued, so it is the model and not the caller that is refused, nothing is queued or charged, and the synchronous route `POST /v2/models/{provider}/{model}` runs it instead."},{"value":"service_unavailable","tier":"transport","meaning":"A service Comfy Router depends on is temporarily unavailable and the caller did nothing wrong. Retry it with backoff: it is the one bucket here whose condition clears on its own, without the caller changing the request and without a concurrency slot freeing, which is what distinguishes it from the other retryable answers (`concurrency_limit_exceeded`, `deadline_exceeded`). It is separate from `internal_error` - which is a `500` and means Router itself failed - so a client can tell \"come back shortly\" from \"this call is not going to work\"."},{"value":"rate_limited","tier":"transport","meaning":"The caller has spent an allowance measured over a window and must wait for that window to roll. It shares `429` with `concurrency_limit_exceeded` and is not the same thing: that one clears the moment one of the caller's own in-flight calls finishes, so retrying in seconds is right, whereas nothing the caller does drains this one early. `detail` names the window, and `Retry-After` the seconds to wait."},{"value":"cancelled","tier":"transport","meaning":"A queued request was withdrawn — through the cancel route, or by an operator — before it produced a result; it is terminal, and it is not by itself a statement about the charge. Cancelling stops Comfy waiting and it does not always stop the partner working, so a request cancelled while it was still `IN_QUEUE` was never dispatched and cannot be charged, whereas one cancelled after it was admitted may still be charged — a partner generation that completes is charged whether or not anyone collected it, which is why the cancel route calls the ask a request rather than a guarantee. It is not `client_disconnected`: that one says nobody is listening any more while a generation may still be running and billable, whereas this says the request itself was withdrawn. A caller polling the status read sees `200` with this in the body, because the request ended and so the read succeeded. Collecting the result of such a request answers `409` in Router's error envelope: that read also worked, and what it found is a request whose terminal state - the caller's own decision - leaves nothing to return. It is deliberately not `410`, which on that route means the result aged out of its retention window, and not a `5xx`, which would report the caller's own cancellation as a Router fault and read to a polling client as worth retrying."},{"value":"queue_timeout","tier":"transport","meaning":"A queued request waited past its queue timeout without ever being admitted. Terminal, unbilled, and it never took a concurrency slot — the job never reached a provider. Deliberately not `deadline_exceeded`, which is the synchronous route's connection bound: a `deadline_exceeded` generation may be running and billable, whereas this one provably never started. It is returned under `504`, which it shares with `provider_timeout` and `deadline_exceeded` because a status can only say that a clock ran out; which clock - the partner's, Comfy's connection bound, or the queue's admission bound - is what `error_type` carries. The request itself is terminal, so submit a new one rather than re-reading this one."},{"value":"request_not_found","tier":"transport","meaning":"The `request_id` names no request of the caller's under this model. It is the second of the two conditions the queued reads' `404` covers; the first is the `{provider}/{model}` ID resolving to no partner model, which is `model_not_found` and carries fuzzy model suggestions. It also covers the right-id / wrong-model URL the path shape refuses, and it is deliberately indistinguishable from a request in another workspace, so a probe with a guessed id learns nothing. A request that has merely aged out of its retention window is `410`, not this."},{"value":"queue_backlog_full","tier":"transport","meaning":"The caller already has too many queued requests waiting to run, so this submit was refused. It shares `429` with `concurrency_limit_exceeded` and is not the same thing: that one is the synchronous route's answer for too many calls in flight at once, whereas the queue accepts a submit at that limit and parks it, and this bucket is the separate bound on how many a caller may leave waiting so that parking cannot mean enqueuing without end. It clears as the caller's own queued requests finish, so retry once some of them complete."},{"value":"result_expired","tier":"transport","meaning":"The request existed and finished, but its result is no longer stored, so the collect has nothing to return. It is returned under `410` and is permanent for that id: re-reading will answer the same way, so do not retry it. It is deliberately not `request_not_found`, which would tell you the id was never valid and invite re-submitting a generation that has already run. Running the model again means submitting a new request. For a workspace under a zero-data-retention agreement, a queued request's result is not kept after it is delivered: it is removed shortly after the first collect, and an uncollected result is removed after a grace period once the request finishes, so store the result on your side when you first collect it."}]}},"X-Comfy-Request-Id":{"description":"Server-generated identifier for this call, present on every Router response - success, 4xx and 5xx alike, because an error response is exactly when a user needs an id to quote in a support request. The same value is written into the call's usage/audit event, which is what lets a complaint about a charge be joined to the charge itself instead of searched for by timestamp.","required":true,"schema":{"type":"string","format":"uuid","example":"6f1a1a6e-6a53-4a5f-9d3a-2b3b0a1f9c21"}},"Retry-After":{"description":"Seconds to wait before sending another request after a `429` carrying `error_type: rate_limited`: the time until the caller's per-minute request allowance has refilled enough to admit one more request. It is sent on every `rate_limited` refusal and on no other answer, so it is absent on a `429` whose `X-Comfy-Error-Type` is `concurrency_limit_exceeded` or `queue_backlog_full`. Nothing the caller does drains it early; a request sent sooner is refused again and spends nothing, but gains nothing either.","required":false,"schema":{"type":"integer","minimum":1,"example":2}}},"content":{"application/json":{"schema":{"type":"object","description":"Router's request-level error body: what is returned when the request never reached the model, or failed for a reason the model itself did not report - auth, quota, an unknown model ID, or provider transport. A model-level validation failure has its own shape, `RouterValidationErrorResponse`, because flattening a FastAPI `detail[]` array into this `detail` string would destroy the per-field granularity an SDK branches on.","properties":{"detail":{"type":"string","description":"Human-readable description of the failure, safe to surface to an end user. Not machine-parsed - branch on `error_type` instead. For `model_not_found` on a retired model, `detail` reads `\u003cid> was retired on \u003cYYYY-MM-DD>; use \u003csuccessor>` when a successor is recorded and visible to the caller, or just `\u003cid> was retired on \u003cYYYY-MM-DD>` when it is not, instead of the usual suggestion list. A successor named here is always a live catalog ID the call can be re-pointed at. A model whose sunset date is still in the future is not retired: it stays listed by `GET /v2/models` and stays runnable until that date. Like the rest of `detail`, this retirement wording is for display and carries no compatibility guarantee.","isRequired":true,"uniqueKey":"detail","typeLabel":"string"},"error_type":{"type":"string","description":"Coarse, machine-readable bucket for a Router failure, mirrored on the `X-Comfy-Error-Type` response header so a caller can branch without parsing the body. The set is closed at twenty values: the six request-level buckets `invalid_input`, `content_policy_violation`, `provider_error`, `provider_timeout`, `insufficient_credits` and `model_not_found`, plus the transport-level `unauthorized`, `forbidden`, `concurrency_limit_exceeded`, `client_disconnected`, `internal_error`, `deadline_exceeded`, `not_enabled`, `service_unavailable`, `rate_limited`, `cancelled`, `queue_timeout`, `request_not_found`, `queue_backlog_full` and `result_expired`. Closed describes the set as documented today, not a bound that holds forever: the set is expected to grow, which is why this is deliberately a plain string and not an `enum`, so a client must treat an unrecognised value as `internal_error` rather than switch exhaustively over the list above and break on the next addition.","example":"invalid_input","x-comfy-error-types":[{"value":"invalid_input","tier":"request","meaning":"The request was rejected before it reached the model - a malformed body, a malformed or expired pagination cursor, an input the model's own schema does not accept, or an `Idempotency-Key` that cannot serve this request (already used for a different request - the method, the path and query, or the body differ - or already consumed by a call whose response cannot be replayed). Sent with `409` in the key cases and with `400`/`422` in the others; the status says which, and the key cases are the ones answered by using a new key rather than by editing the request."},{"value":"content_policy_violation","tier":"request","meaning":"The provider refused the request on content-policy grounds. The refusal is deterministic: re-sending the same input will be refused again."},{"value":"provider_error","tier":"request","meaning":"The partner provider reported a failure of its own, or returned a response Router could not interpret as a result."},{"value":"provider_timeout","tier":"request","meaning":"The partner provider did not answer within its deadline. This bucket is the provider timing out and never Router's own server deadline, which is reported as `deadline_exceeded` - the two share `504` and are separated because they name different causes: this one says the partner failed, that one says Comfy stopped holding the connection."},{"value":"insufficient_credits","tier":"request","meaning":"The calling workspace does not have enough credits to run the model."},{"value":"model_not_found","tier":"request","meaning":"The `{provider}/{model}` ID names no model Router can run: an unknown provider, an unenrolled id, one the catalog has retired past its sunset date, or a catalogued ID the provider does not currently serve for Comfy. A retired id's `detail` reads `\u003cid> was retired on \u003cYYYY-MM-DD>; use \u003csuccessor>` when a successor is recorded and not withheld, or just `\u003cid> was retired on \u003cYYYY-MM-DD>` when it is not, instead of a suggestion list; the successor named for a retired id is always a live catalog ID you can re-point the call at, and a successor is dropped from `detail` either because the table records none, or because the recorded one is currently withheld behind an embargo the caller cannot see. A model whose sunset is still in the future is not withdrawn: it stays listed by `GET /v2/models` and stays runnable until the date, so a listing taken today remains the answer to what runs today. Otherwise `detail` carries up to three suggestions drawn from the models the caller is entitled to see, except for a catalogued ID the provider does not currently serve for Comfy, whose response carries no suggestions."},{"value":"unauthorized","tier":"transport","meaning":"The request carried no usable credential."},{"value":"forbidden","tier":"transport","meaning":"The credential is valid but is not entitled to this model or this operation."},{"value":"concurrency_limit_exceeded","tier":"transport","meaning":"The workspace already has as many calls in flight as it is allowed; retry once one of them finishes. It carries one further condition on the run route, on a `409` rather than the `429` above: another call is already in flight for the `Idempotency-Key` this request presented. Re-send the same key after `Retry-After` seconds to collect that call's result."},{"value":"client_disconnected","tier":"transport","meaning":"The caller closed the connection before Router could return a result. It is logged rather than delivered - there is no socket left to write it to - and it is an attribution, not a billing outcome: a provider generation that completed is billed regardless of whether the caller received the response."},{"value":"internal_error","tier":"transport","meaning":"Router itself failed. It is also the value a client should treat any unrecognized bucket as, so a later addition to the set does not break a client generated before it."},{"value":"deadline_exceeded","tier":"transport","meaning":"Comfy stopped holding the connection at its own configured bound before an answer arrived. It shares `504` with `provider_timeout` and the pair says which side ran out of time; this one is Comfy's own bound, so nothing about the request was rejected and the same request may be retried. It says nothing about the charge: a provider generation that completed is billed regardless of whether the caller received the response. Retry it with the same `Idempotency-Key`: when the provider had already accepted the generation, the retry collects that generation rather than dispatching another, and a `Retry-After` on the `504` says when to ask."},{"value":"not_enabled","tier":"transport","meaning":"Comfy Router is not switched on for this caller yet. Nothing about the request is wrong and the model exists, which is why this is not `model_not_found`; it shares `403` with `forbidden` and is not the same thing, because `forbidden` is an entitlement decision about the caller while this is a state of the rollout. It is terminal: do not retry, and do not treat it as an outage. The one exception to \"about the caller\" is the queued submit, which also answers `not_enabled` for a model whose partner answers a generation directly as bytes: that model cannot yet be queued, so it is the model and not the caller that is refused, nothing is queued or charged, and the synchronous route `POST /v2/models/{provider}/{model}` runs it instead."},{"value":"service_unavailable","tier":"transport","meaning":"A service Comfy Router depends on is temporarily unavailable and the caller did nothing wrong. Retry it with backoff: it is the one bucket here whose condition clears on its own, without the caller changing the request and without a concurrency slot freeing, which is what distinguishes it from the other retryable answers (`concurrency_limit_exceeded`, `deadline_exceeded`). It is separate from `internal_error` - which is a `500` and means Router itself failed - so a client can tell \"come back shortly\" from \"this call is not going to work\"."},{"value":"rate_limited","tier":"transport","meaning":"The caller has spent an allowance measured over a window and must wait for that window to roll. It shares `429` with `concurrency_limit_exceeded` and is not the same thing: that one clears the moment one of the caller's own in-flight calls finishes, so retrying in seconds is right, whereas nothing the caller does drains this one early. `detail` names the window, and `Retry-After` the seconds to wait."},{"value":"cancelled","tier":"transport","meaning":"A queued request was withdrawn — through the cancel route, or by an operator — before it produced a result; it is terminal, and it is not by itself a statement about the charge. Cancelling stops Comfy waiting and it does not always stop the partner working, so a request cancelled while it was still `IN_QUEUE` was never dispatched and cannot be charged, whereas one cancelled after it was admitted may still be charged — a partner generation that completes is charged whether or not anyone collected it, which is why the cancel route calls the ask a request rather than a guarantee. It is not `client_disconnected`: that one says nobody is listening any more while a generation may still be running and billable, whereas this says the request itself was withdrawn. A caller polling the status read sees `200` with this in the body, because the request ended and so the read succeeded. Collecting the result of such a request answers `409` in Router's error envelope: that read also worked, and what it found is a request whose terminal state - the caller's own decision - leaves nothing to return. It is deliberately not `410`, which on that route means the result aged out of its retention window, and not a `5xx`, which would report the caller's own cancellation as a Router fault and read to a polling client as worth retrying."},{"value":"queue_timeout","tier":"transport","meaning":"A queued request waited past its queue timeout without ever being admitted. Terminal, unbilled, and it never took a concurrency slot — the job never reached a provider. Deliberately not `deadline_exceeded`, which is the synchronous route's connection bound: a `deadline_exceeded` generation may be running and billable, whereas this one provably never started. It is returned under `504`, which it shares with `provider_timeout` and `deadline_exceeded` because a status can only say that a clock ran out; which clock - the partner's, Comfy's connection bound, or the queue's admission bound - is what `error_type` carries. The request itself is terminal, so submit a new one rather than re-reading this one."},{"value":"request_not_found","tier":"transport","meaning":"The `request_id` names no request of the caller's under this model. It is the second of the two conditions the queued reads' `404` covers; the first is the `{provider}/{model}` ID resolving to no partner model, which is `model_not_found` and carries fuzzy model suggestions. It also covers the right-id / wrong-model URL the path shape refuses, and it is deliberately indistinguishable from a request in another workspace, so a probe with a guessed id learns nothing. A request that has merely aged out of its retention window is `410`, not this."},{"value":"queue_backlog_full","tier":"transport","meaning":"The caller already has too many queued requests waiting to run, so this submit was refused. It shares `429` with `concurrency_limit_exceeded` and is not the same thing: that one is the synchronous route's answer for too many calls in flight at once, whereas the queue accepts a submit at that limit and parks it, and this bucket is the separate bound on how many a caller may leave waiting so that parking cannot mean enqueuing without end. It clears as the caller's own queued requests finish, so retry once some of them complete."},{"value":"result_expired","tier":"transport","meaning":"The request existed and finished, but its result is no longer stored, so the collect has nothing to return. It is returned under `410` and is permanent for that id: re-reading will answer the same way, so do not retry it. It is deliberately not `request_not_found`, which would tell you the id was never valid and invite re-submitting a generation that has already run. Running the model again means submitting a new request. For a workspace under a zero-data-retention agreement, a queued request's result is not kept after it is delivered: it is removed shortly after the first collect, and an uncollected result is removed after a grace period once the request finishes, so store the result on your side when you first collect it."}],"isRequired":true,"uniqueKey":"error_type","typeLabel":"string"},"upstream_detail":{"type":"string","description":"A bounded, sanitized reason the model provider gave for rejecting the request, present only when `error_type` is `invalid_input` and `X-Comfy-Upstream-Status` is a provider `4xx` or `2xx` - i.e. the provider refused the request as malformed and said why. Usually that status is a `4xx`; it is a `2xx` for a provider that reports a rejected generation inside a success envelope (a BytePlus failed-task poll is HTTP `200` with the reason in its body). Absent on every other failure, including provider `5xx`, transport failures, content-policy refusals and any refusal Router raised about itself. It mirrors the `X-Comfy-Upstream-Detail` header. The queued collect (`GET /v2/models/{provider}/{model}/requests/{request_id}`) of a run that ended `invalid_input` carries the same reason in this field on its first collect, which then deletes it from the request: a later collect normally answers the same `error_type` and `detail` without it, so read it from the first collect. That read sends neither header.","uniqueKey":"upstream_detail","typeLabel":"string"},"refusal_subject":{"type":"string","description":"Which input or output a content-policy refusal was about, as a Router-level closed vocabulary: `input`, `output`, `input_text`, `input_image`, `input_video`, `input_audio`, `output_text`, `output_image`, `output_video`, `output_audio`. The bare `input` / `output` values name the side when the provider did not name a modality. Present only when `error_type` is `content_policy_violation` and the provider named the refused subject with a machine-readable code; absent otherwise. Never provider text. Named today for BytePlus, Runway, BFL, Gemini, Veo, Vertex, xAI and Wan refusals, and for the MiniMax Router's Nano Banana legs' Gemini refusals; a provider whose refusal does not say which side it was about leaves it absent. It mirrors the `X-Comfy-Refusal-Subject` header.","uniqueKey":"refusal_subject","typeLabel":"string"},"denied_reason":{"type":"string","description":"Billing's policy branch for a partner-node spend denial - `no_funds` when the billed wallet is empty, `unspecified` when the call was refused without a funds reading saying so. Present only when `error_type` is `insufficient_credits` and the deployment reports wallet facts; absent otherwise. A machine-readable code, not display text: show `detail`, branch on this.","uniqueKey":"denied_reason","typeLabel":"string"},"billed_workspace":{"type":"object","description":"The wallet a refused call would have charged, on `RouterErrorResponse.billed_workspace`. Answers \"which wallet is empty?\" - it is not necessarily the workspace the caller's UI currently has selected, and a team member's personal credential names their personal wallet here even while a funded team is open. Present only alongside `denied_reason`.","properties":{"type":{"type":"string","description":"`personal` or `team`. An open string: treat any other value as personal.","isRequired":true,"uniqueKey":"billed_workspace.type","typeLabel":"string"},"id":{"type":"string","description":"The Cloud workspace id. Absent on the legacy rail.","uniqueKey":"billed_workspace.id","typeLabel":"string"},"rail":{"type":"string","description":"`legacy` when the call bills the caller's pre-workspace Metronome customer rather than a Cloud workspace; that customer has no workspace id. Absent for a Cloud workspace.","uniqueKey":"billed_workspace.rail","typeLabel":"string"}},"required":["type"],"uniqueKey":"billed_workspace","typeLabel":"object"},"credential_kind":{"type":"string","description":"How the refused request authenticated - `personal_api_key`, `team_api_key`, `personal_session` or `team_session`. Answers \"which credential do I switch to bill the other wallet?\". It is not a permission and grants nothing. Present only alongside `denied_reason`.","uniqueKey":"credential_kind","typeLabel":"string"}},"required":["detail","error_type"],"uniqueKey":"","typeLabel":"object"},"examples":{"Example":{"title":"Example","value":{"detail":"\u003cstring>","error_type":"invalid_input","upstream_detail":"\u003cstring>","refusal_subject":"\u003cstring>","denied_reason":"\u003cstring>","billed_workspace":{"type":"\u003cstring>","id":"\u003cstring>","rail":"\u003cstring>"},"credential_kind":"\u003cstring>"}}},"exampleType":"generated"}},"exampleType":"generated"},"1311734b-13bb-4c01-a675-facb770152fa":{"description":"A Router request-level failure - the request never reached the model, or failed for a reason the model itself did not report. The body is `RouterErrorResponse` and the bucket is repeated on `X-Comfy-Error-Type`.","headers":{"X-Comfy-Error-Type":{"description":"Coarse, machine-readable bucket for the failure, set by Router on every error response. It carries the same value as `RouterErrorResponse.error_type`, and on the `422` it is the only machine-readable bucket, because that body is the FastAPI `detail[]` shape and has no `error_type` field of its own. A client can therefore branch on this header alone, before deciding which of the two Router error bodies it received.","required":true,"schema":{"type":"string","description":"Coarse, machine-readable bucket for a Router failure, mirrored on the `X-Comfy-Error-Type` response header so a caller can branch without parsing the body. The set is closed at twenty values: the six request-level buckets `invalid_input`, `content_policy_violation`, `provider_error`, `provider_timeout`, `insufficient_credits` and `model_not_found`, plus the transport-level `unauthorized`, `forbidden`, `concurrency_limit_exceeded`, `client_disconnected`, `internal_error`, `deadline_exceeded`, `not_enabled`, `service_unavailable`, `rate_limited`, `cancelled`, `queue_timeout`, `request_not_found`, `queue_backlog_full` and `result_expired`. Closed describes the set as documented today, not a bound that holds forever: the set is expected to grow, which is why this is deliberately a plain string and not an `enum`, so a client must treat an unrecognised value as `internal_error` rather than switch exhaustively over the list above and break on the next addition.","example":"invalid_input","x-comfy-error-types":[{"value":"invalid_input","tier":"request","meaning":"The request was rejected before it reached the model - a malformed body, a malformed or expired pagination cursor, an input the model's own schema does not accept, or an `Idempotency-Key` that cannot serve this request (already used for a different request - the method, the path and query, or the body differ - or already consumed by a call whose response cannot be replayed). Sent with `409` in the key cases and with `400`/`422` in the others; the status says which, and the key cases are the ones answered by using a new key rather than by editing the request."},{"value":"content_policy_violation","tier":"request","meaning":"The provider refused the request on content-policy grounds. The refusal is deterministic: re-sending the same input will be refused again."},{"value":"provider_error","tier":"request","meaning":"The partner provider reported a failure of its own, or returned a response Router could not interpret as a result."},{"value":"provider_timeout","tier":"request","meaning":"The partner provider did not answer within its deadline. This bucket is the provider timing out and never Router's own server deadline, which is reported as `deadline_exceeded` - the two share `504` and are separated because they name different causes: this one says the partner failed, that one says Comfy stopped holding the connection."},{"value":"insufficient_credits","tier":"request","meaning":"The calling workspace does not have enough credits to run the model."},{"value":"model_not_found","tier":"request","meaning":"The `{provider}/{model}` ID names no model Router can run: an unknown provider, an unenrolled id, one the catalog has retired past its sunset date, or a catalogued ID the provider does not currently serve for Comfy. A retired id's `detail` reads `\u003cid> was retired on \u003cYYYY-MM-DD>; use \u003csuccessor>` when a successor is recorded and not withheld, or just `\u003cid> was retired on \u003cYYYY-MM-DD>` when it is not, instead of a suggestion list; the successor named for a retired id is always a live catalog ID you can re-point the call at, and a successor is dropped from `detail` either because the table records none, or because the recorded one is currently withheld behind an embargo the caller cannot see. A model whose sunset is still in the future is not withdrawn: it stays listed by `GET /v2/models` and stays runnable until the date, so a listing taken today remains the answer to what runs today. Otherwise `detail` carries up to three suggestions drawn from the models the caller is entitled to see, except for a catalogued ID the provider does not currently serve for Comfy, whose response carries no suggestions."},{"value":"unauthorized","tier":"transport","meaning":"The request carried no usable credential."},{"value":"forbidden","tier":"transport","meaning":"The credential is valid but is not entitled to this model or this operation."},{"value":"concurrency_limit_exceeded","tier":"transport","meaning":"The workspace already has as many calls in flight as it is allowed; retry once one of them finishes. It carries one further condition on the run route, on a `409` rather than the `429` above: another call is already in flight for the `Idempotency-Key` this request presented. Re-send the same key after `Retry-After` seconds to collect that call's result."},{"value":"client_disconnected","tier":"transport","meaning":"The caller closed the connection before Router could return a result. It is logged rather than delivered - there is no socket left to write it to - and it is an attribution, not a billing outcome: a provider generation that completed is billed regardless of whether the caller received the response."},{"value":"internal_error","tier":"transport","meaning":"Router itself failed. It is also the value a client should treat any unrecognized bucket as, so a later addition to the set does not break a client generated before it."},{"value":"deadline_exceeded","tier":"transport","meaning":"Comfy stopped holding the connection at its own configured bound before an answer arrived. It shares `504` with `provider_timeout` and the pair says which side ran out of time; this one is Comfy's own bound, so nothing about the request was rejected and the same request may be retried. It says nothing about the charge: a provider generation that completed is billed regardless of whether the caller received the response. Retry it with the same `Idempotency-Key`: when the provider had already accepted the generation, the retry collects that generation rather than dispatching another, and a `Retry-After` on the `504` says when to ask."},{"value":"not_enabled","tier":"transport","meaning":"Comfy Router is not switched on for this caller yet. Nothing about the request is wrong and the model exists, which is why this is not `model_not_found`; it shares `403` with `forbidden` and is not the same thing, because `forbidden` is an entitlement decision about the caller while this is a state of the rollout. It is terminal: do not retry, and do not treat it as an outage. The one exception to \"about the caller\" is the queued submit, which also answers `not_enabled` for a model whose partner answers a generation directly as bytes: that model cannot yet be queued, so it is the model and not the caller that is refused, nothing is queued or charged, and the synchronous route `POST /v2/models/{provider}/{model}` runs it instead."},{"value":"service_unavailable","tier":"transport","meaning":"A service Comfy Router depends on is temporarily unavailable and the caller did nothing wrong. Retry it with backoff: it is the one bucket here whose condition clears on its own, without the caller changing the request and without a concurrency slot freeing, which is what distinguishes it from the other retryable answers (`concurrency_limit_exceeded`, `deadline_exceeded`). It is separate from `internal_error` - which is a `500` and means Router itself failed - so a client can tell \"come back shortly\" from \"this call is not going to work\"."},{"value":"rate_limited","tier":"transport","meaning":"The caller has spent an allowance measured over a window and must wait for that window to roll. It shares `429` with `concurrency_limit_exceeded` and is not the same thing: that one clears the moment one of the caller's own in-flight calls finishes, so retrying in seconds is right, whereas nothing the caller does drains this one early. `detail` names the window, and `Retry-After` the seconds to wait."},{"value":"cancelled","tier":"transport","meaning":"A queued request was withdrawn — through the cancel route, or by an operator — before it produced a result; it is terminal, and it is not by itself a statement about the charge. Cancelling stops Comfy waiting and it does not always stop the partner working, so a request cancelled while it was still `IN_QUEUE` was never dispatched and cannot be charged, whereas one cancelled after it was admitted may still be charged — a partner generation that completes is charged whether or not anyone collected it, which is why the cancel route calls the ask a request rather than a guarantee. It is not `client_disconnected`: that one says nobody is listening any more while a generation may still be running and billable, whereas this says the request itself was withdrawn. A caller polling the status read sees `200` with this in the body, because the request ended and so the read succeeded. Collecting the result of such a request answers `409` in Router's error envelope: that read also worked, and what it found is a request whose terminal state - the caller's own decision - leaves nothing to return. It is deliberately not `410`, which on that route means the result aged out of its retention window, and not a `5xx`, which would report the caller's own cancellation as a Router fault and read to a polling client as worth retrying."},{"value":"queue_timeout","tier":"transport","meaning":"A queued request waited past its queue timeout without ever being admitted. Terminal, unbilled, and it never took a concurrency slot — the job never reached a provider. Deliberately not `deadline_exceeded`, which is the synchronous route's connection bound: a `deadline_exceeded` generation may be running and billable, whereas this one provably never started. It is returned under `504`, which it shares with `provider_timeout` and `deadline_exceeded` because a status can only say that a clock ran out; which clock - the partner's, Comfy's connection bound, or the queue's admission bound - is what `error_type` carries. The request itself is terminal, so submit a new one rather than re-reading this one."},{"value":"request_not_found","tier":"transport","meaning":"The `request_id` names no request of the caller's under this model. It is the second of the two conditions the queued reads' `404` covers; the first is the `{provider}/{model}` ID resolving to no partner model, which is `model_not_found` and carries fuzzy model suggestions. It also covers the right-id / wrong-model URL the path shape refuses, and it is deliberately indistinguishable from a request in another workspace, so a probe with a guessed id learns nothing. A request that has merely aged out of its retention window is `410`, not this."},{"value":"queue_backlog_full","tier":"transport","meaning":"The caller already has too many queued requests waiting to run, so this submit was refused. It shares `429` with `concurrency_limit_exceeded` and is not the same thing: that one is the synchronous route's answer for too many calls in flight at once, whereas the queue accepts a submit at that limit and parks it, and this bucket is the separate bound on how many a caller may leave waiting so that parking cannot mean enqueuing without end. It clears as the caller's own queued requests finish, so retry once some of them complete."},{"value":"result_expired","tier":"transport","meaning":"The request existed and finished, but its result is no longer stored, so the collect has nothing to return. It is returned under `410` and is permanent for that id: re-reading will answer the same way, so do not retry it. It is deliberately not `request_not_found`, which would tell you the id was never valid and invite re-submitting a generation that has already run. Running the model again means submitting a new request. For a workspace under a zero-data-retention agreement, a queued request's result is not kept after it is delivered: it is removed shortly after the first collect, and an uncollected result is removed after a grace period once the request finishes, so store the result on your side when you first collect it."}]}},"X-Comfy-Request-Id":{"description":"Server-generated identifier for this call, present on every Router response - success, 4xx and 5xx alike, because an error response is exactly when a user needs an id to quote in a support request. The same value is written into the call's usage/audit event, which is what lets a complaint about a charge be joined to the charge itself instead of searched for by timestamp.","required":true,"schema":{"type":"string","format":"uuid","example":"6f1a1a6e-6a53-4a5f-9d3a-2b3b0a1f9c21"}}},"content":{"application/json":{"schema":{"type":"object","description":"Router's request-level error body: what is returned when the request never reached the model, or failed for a reason the model itself did not report - auth, quota, an unknown model ID, or provider transport. A model-level validation failure has its own shape, `RouterValidationErrorResponse`, because flattening a FastAPI `detail[]` array into this `detail` string would destroy the per-field granularity an SDK branches on.","properties":{"detail":{"type":"string","description":"Human-readable description of the failure, safe to surface to an end user. Not machine-parsed - branch on `error_type` instead. For `model_not_found` on a retired model, `detail` reads `\u003cid> was retired on \u003cYYYY-MM-DD>; use \u003csuccessor>` when a successor is recorded and visible to the caller, or just `\u003cid> was retired on \u003cYYYY-MM-DD>` when it is not, instead of the usual suggestion list. A successor named here is always a live catalog ID the call can be re-pointed at. A model whose sunset date is still in the future is not retired: it stays listed by `GET /v2/models` and stays runnable until that date. Like the rest of `detail`, this retirement wording is for display and carries no compatibility guarantee.","isRequired":true,"uniqueKey":"detail","typeLabel":"string"},"error_type":{"type":"string","description":"Coarse, machine-readable bucket for a Router failure, mirrored on the `X-Comfy-Error-Type` response header so a caller can branch without parsing the body. The set is closed at twenty values: the six request-level buckets `invalid_input`, `content_policy_violation`, `provider_error`, `provider_timeout`, `insufficient_credits` and `model_not_found`, plus the transport-level `unauthorized`, `forbidden`, `concurrency_limit_exceeded`, `client_disconnected`, `internal_error`, `deadline_exceeded`, `not_enabled`, `service_unavailable`, `rate_limited`, `cancelled`, `queue_timeout`, `request_not_found`, `queue_backlog_full` and `result_expired`. Closed describes the set as documented today, not a bound that holds forever: the set is expected to grow, which is why this is deliberately a plain string and not an `enum`, so a client must treat an unrecognised value as `internal_error` rather than switch exhaustively over the list above and break on the next addition.","example":"invalid_input","x-comfy-error-types":[{"value":"invalid_input","tier":"request","meaning":"The request was rejected before it reached the model - a malformed body, a malformed or expired pagination cursor, an input the model's own schema does not accept, or an `Idempotency-Key` that cannot serve this request (already used for a different request - the method, the path and query, or the body differ - or already consumed by a call whose response cannot be replayed). Sent with `409` in the key cases and with `400`/`422` in the others; the status says which, and the key cases are the ones answered by using a new key rather than by editing the request."},{"value":"content_policy_violation","tier":"request","meaning":"The provider refused the request on content-policy grounds. The refusal is deterministic: re-sending the same input will be refused again."},{"value":"provider_error","tier":"request","meaning":"The partner provider reported a failure of its own, or returned a response Router could not interpret as a result."},{"value":"provider_timeout","tier":"request","meaning":"The partner provider did not answer within its deadline. This bucket is the provider timing out and never Router's own server deadline, which is reported as `deadline_exceeded` - the two share `504` and are separated because they name different causes: this one says the partner failed, that one says Comfy stopped holding the connection."},{"value":"insufficient_credits","tier":"request","meaning":"The calling workspace does not have enough credits to run the model."},{"value":"model_not_found","tier":"request","meaning":"The `{provider}/{model}` ID names no model Router can run: an unknown provider, an unenrolled id, one the catalog has retired past its sunset date, or a catalogued ID the provider does not currently serve for Comfy. A retired id's `detail` reads `\u003cid> was retired on \u003cYYYY-MM-DD>; use \u003csuccessor>` when a successor is recorded and not withheld, or just `\u003cid> was retired on \u003cYYYY-MM-DD>` when it is not, instead of a suggestion list; the successor named for a retired id is always a live catalog ID you can re-point the call at, and a successor is dropped from `detail` either because the table records none, or because the recorded one is currently withheld behind an embargo the caller cannot see. A model whose sunset is still in the future is not withdrawn: it stays listed by `GET /v2/models` and stays runnable until the date, so a listing taken today remains the answer to what runs today. Otherwise `detail` carries up to three suggestions drawn from the models the caller is entitled to see, except for a catalogued ID the provider does not currently serve for Comfy, whose response carries no suggestions."},{"value":"unauthorized","tier":"transport","meaning":"The request carried no usable credential."},{"value":"forbidden","tier":"transport","meaning":"The credential is valid but is not entitled to this model or this operation."},{"value":"concurrency_limit_exceeded","tier":"transport","meaning":"The workspace already has as many calls in flight as it is allowed; retry once one of them finishes. It carries one further condition on the run route, on a `409` rather than the `429` above: another call is already in flight for the `Idempotency-Key` this request presented. Re-send the same key after `Retry-After` seconds to collect that call's result."},{"value":"client_disconnected","tier":"transport","meaning":"The caller closed the connection before Router could return a result. It is logged rather than delivered - there is no socket left to write it to - and it is an attribution, not a billing outcome: a provider generation that completed is billed regardless of whether the caller received the response."},{"value":"internal_error","tier":"transport","meaning":"Router itself failed. It is also the value a client should treat any unrecognized bucket as, so a later addition to the set does not break a client generated before it."},{"value":"deadline_exceeded","tier":"transport","meaning":"Comfy stopped holding the connection at its own configured bound before an answer arrived. It shares `504` with `provider_timeout` and the pair says which side ran out of time; this one is Comfy's own bound, so nothing about the request was rejected and the same request may be retried. It says nothing about the charge: a provider generation that completed is billed regardless of whether the caller received the response. Retry it with the same `Idempotency-Key`: when the provider had already accepted the generation, the retry collects that generation rather than dispatching another, and a `Retry-After` on the `504` says when to ask."},{"value":"not_enabled","tier":"transport","meaning":"Comfy Router is not switched on for this caller yet. Nothing about the request is wrong and the model exists, which is why this is not `model_not_found`; it shares `403` with `forbidden` and is not the same thing, because `forbidden` is an entitlement decision about the caller while this is a state of the rollout. It is terminal: do not retry, and do not treat it as an outage. The one exception to \"about the caller\" is the queued submit, which also answers `not_enabled` for a model whose partner answers a generation directly as bytes: that model cannot yet be queued, so it is the model and not the caller that is refused, nothing is queued or charged, and the synchronous route `POST /v2/models/{provider}/{model}` runs it instead."},{"value":"service_unavailable","tier":"transport","meaning":"A service Comfy Router depends on is temporarily unavailable and the caller did nothing wrong. Retry it with backoff: it is the one bucket here whose condition clears on its own, without the caller changing the request and without a concurrency slot freeing, which is what distinguishes it from the other retryable answers (`concurrency_limit_exceeded`, `deadline_exceeded`). It is separate from `internal_error` - which is a `500` and means Router itself failed - so a client can tell \"come back shortly\" from \"this call is not going to work\"."},{"value":"rate_limited","tier":"transport","meaning":"The caller has spent an allowance measured over a window and must wait for that window to roll. It shares `429` with `concurrency_limit_exceeded` and is not the same thing: that one clears the moment one of the caller's own in-flight calls finishes, so retrying in seconds is right, whereas nothing the caller does drains this one early. `detail` names the window, and `Retry-After` the seconds to wait."},{"value":"cancelled","tier":"transport","meaning":"A queued request was withdrawn — through the cancel route, or by an operator — before it produced a result; it is terminal, and it is not by itself a statement about the charge. Cancelling stops Comfy waiting and it does not always stop the partner working, so a request cancelled while it was still `IN_QUEUE` was never dispatched and cannot be charged, whereas one cancelled after it was admitted may still be charged — a partner generation that completes is charged whether or not anyone collected it, which is why the cancel route calls the ask a request rather than a guarantee. It is not `client_disconnected`: that one says nobody is listening any more while a generation may still be running and billable, whereas this says the request itself was withdrawn. A caller polling the status read sees `200` with this in the body, because the request ended and so the read succeeded. Collecting the result of such a request answers `409` in Router's error envelope: that read also worked, and what it found is a request whose terminal state - the caller's own decision - leaves nothing to return. It is deliberately not `410`, which on that route means the result aged out of its retention window, and not a `5xx`, which would report the caller's own cancellation as a Router fault and read to a polling client as worth retrying."},{"value":"queue_timeout","tier":"transport","meaning":"A queued request waited past its queue timeout without ever being admitted. Terminal, unbilled, and it never took a concurrency slot — the job never reached a provider. Deliberately not `deadline_exceeded`, which is the synchronous route's connection bound: a `deadline_exceeded` generation may be running and billable, whereas this one provably never started. It is returned under `504`, which it shares with `provider_timeout` and `deadline_exceeded` because a status can only say that a clock ran out; which clock - the partner's, Comfy's connection bound, or the queue's admission bound - is what `error_type` carries. The request itself is terminal, so submit a new one rather than re-reading this one."},{"value":"request_not_found","tier":"transport","meaning":"The `request_id` names no request of the caller's under this model. It is the second of the two conditions the queued reads' `404` covers; the first is the `{provider}/{model}` ID resolving to no partner model, which is `model_not_found` and carries fuzzy model suggestions. It also covers the right-id / wrong-model URL the path shape refuses, and it is deliberately indistinguishable from a request in another workspace, so a probe with a guessed id learns nothing. A request that has merely aged out of its retention window is `410`, not this."},{"value":"queue_backlog_full","tier":"transport","meaning":"The caller already has too many queued requests waiting to run, so this submit was refused. It shares `429` with `concurrency_limit_exceeded` and is not the same thing: that one is the synchronous route's answer for too many calls in flight at once, whereas the queue accepts a submit at that limit and parks it, and this bucket is the separate bound on how many a caller may leave waiting so that parking cannot mean enqueuing without end. It clears as the caller's own queued requests finish, so retry once some of them complete."},{"value":"result_expired","tier":"transport","meaning":"The request existed and finished, but its result is no longer stored, so the collect has nothing to return. It is returned under `410` and is permanent for that id: re-reading will answer the same way, so do not retry it. It is deliberately not `request_not_found`, which would tell you the id was never valid and invite re-submitting a generation that has already run. Running the model again means submitting a new request. For a workspace under a zero-data-retention agreement, a queued request's result is not kept after it is delivered: it is removed shortly after the first collect, and an uncollected result is removed after a grace period once the request finishes, so store the result on your side when you first collect it."}],"isRequired":true,"uniqueKey":"error_type","typeLabel":"string"},"upstream_detail":{"type":"string","description":"A bounded, sanitized reason the model provider gave for rejecting the request, present only when `error_type` is `invalid_input` and `X-Comfy-Upstream-Status` is a provider `4xx` or `2xx` - i.e. the provider refused the request as malformed and said why. Usually that status is a `4xx`; it is a `2xx` for a provider that reports a rejected generation inside a success envelope (a BytePlus failed-task poll is HTTP `200` with the reason in its body). Absent on every other failure, including provider `5xx`, transport failures, content-policy refusals and any refusal Router raised about itself. It mirrors the `X-Comfy-Upstream-Detail` header. The queued collect (`GET /v2/models/{provider}/{model}/requests/{request_id}`) of a run that ended `invalid_input` carries the same reason in this field on its first collect, which then deletes it from the request: a later collect normally answers the same `error_type` and `detail` without it, so read it from the first collect. That read sends neither header.","uniqueKey":"upstream_detail","typeLabel":"string"},"refusal_subject":{"type":"string","description":"Which input or output a content-policy refusal was about, as a Router-level closed vocabulary: `input`, `output`, `input_text`, `input_image`, `input_video`, `input_audio`, `output_text`, `output_image`, `output_video`, `output_audio`. The bare `input` / `output` values name the side when the provider did not name a modality. Present only when `error_type` is `content_policy_violation` and the provider named the refused subject with a machine-readable code; absent otherwise. Never provider text. Named today for BytePlus, Runway, BFL, Gemini, Veo, Vertex, xAI and Wan refusals, and for the MiniMax Router's Nano Banana legs' Gemini refusals; a provider whose refusal does not say which side it was about leaves it absent. It mirrors the `X-Comfy-Refusal-Subject` header.","uniqueKey":"refusal_subject","typeLabel":"string"},"denied_reason":{"type":"string","description":"Billing's policy branch for a partner-node spend denial - `no_funds` when the billed wallet is empty, `unspecified` when the call was refused without a funds reading saying so. Present only when `error_type` is `insufficient_credits` and the deployment reports wallet facts; absent otherwise. A machine-readable code, not display text: show `detail`, branch on this.","uniqueKey":"denied_reason","typeLabel":"string"},"billed_workspace":{"type":"object","description":"The wallet a refused call would have charged, on `RouterErrorResponse.billed_workspace`. Answers \"which wallet is empty?\" - it is not necessarily the workspace the caller's UI currently has selected, and a team member's personal credential names their personal wallet here even while a funded team is open. Present only alongside `denied_reason`.","properties":{"type":{"type":"string","description":"`personal` or `team`. An open string: treat any other value as personal.","isRequired":true,"uniqueKey":"billed_workspace.type","typeLabel":"string"},"id":{"type":"string","description":"The Cloud workspace id. Absent on the legacy rail.","uniqueKey":"billed_workspace.id","typeLabel":"string"},"rail":{"type":"string","description":"`legacy` when the call bills the caller's pre-workspace Metronome customer rather than a Cloud workspace; that customer has no workspace id. Absent for a Cloud workspace.","uniqueKey":"billed_workspace.rail","typeLabel":"string"}},"required":["type"],"uniqueKey":"billed_workspace","typeLabel":"object"},"credential_kind":{"type":"string","description":"How the refused request authenticated - `personal_api_key`, `team_api_key`, `personal_session` or `team_session`. Answers \"which credential do I switch to bill the other wallet?\". It is not a permission and grants nothing. Present only alongside `denied_reason`.","uniqueKey":"credential_kind","typeLabel":"string"}},"required":["detail","error_type"],"uniqueKey":"","typeLabel":"object"},"examples":{"Example":{"title":"Example","value":{"detail":"\u003cstring>","error_type":"invalid_input","upstream_detail":"\u003cstring>","refusal_subject":"\u003cstring>","denied_reason":"\u003cstring>","billed_workspace":{"type":"\u003cstring>","id":"\u003cstring>","rail":"\u003cstring>"},"credential_kind":"\u003cstring>"}}},"exampleType":"generated"}},"exampleType":"generated"}},"security":{"a4806511-f591-4bf5-84f7-24b03a60353f":{"BearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"JWT","description":"Bearer token authentication. Normally a Firebase or Cloud JWT. A 'comfyui-' prefixed API key is also accepted in this header: the prefix classifies the value as an API key and it is validated exactly as if it had been sent in X-API-Key.","scopes":[],"schemeName":"BearerAuth"}},"0d5bd07c-4671-4644-bb5e-411e019d9b9e":{"ApiKeyAuth":{"type":"apiKey","in":"header","name":"X-API-Key","description":"API key authentication. Send the key in the X-API-Key header; keys are prefixed with 'comfyui-' and are generated from user account settings. The same 'comfyui-' key is also accepted in Authorization: Bearer (see BearerAuth), and when both headers carry a key, X-API-Key wins.","scopes":[],"schemeName":"ApiKeyAuth"}}},"servers":{"bf9722b0-5952-4eeb-9e69-c43ede83ce5a":{"url":"https://api.comfy.org"}},"processedSecurityOptions":[{"schemes":[{"scheme":{"type":"http","scheme":"bearer","bearerFormat":"JWT","description":"Bearer token authentication. Normally a Firebase or Cloud JWT. A 'comfyui-' prefixed API key is also accepted in this header: the prefix classifies the value as an API key and it is validated exactly as if it had been sent in X-API-Key.","scopes":[],"schemeName":"BearerAuth"},"schema":{"title":"Bearer Auth","type":"string","isRequired":true,"description":"Bearer token authentication. Normally a Firebase or Cloud JWT. A 'comfyui-' prefixed API key is also accepted in this header: the prefix classifies the value as an API key and it is validated exactly as if it had been sent in X-API-Key.","format":"bearer","typeLabel":"string\u003cbearer>","deprecated":false},"schemeName":"BearerAuth","name":"Authorization"}],"title":"BearerAuth"},{"schemes":[{"scheme":{"type":"apiKey","in":"header","name":"X-API-Key","description":"API key authentication. Send the key in the X-API-Key header; keys are prefixed with 'comfyui-' and are generated from user account settings. The same 'comfyui-' key is also accepted in Authorization: Bearer (see BearerAuth), and when both headers carry a key, X-API-Key wins.","scopes":[],"schemeName":"ApiKeyAuth"},"schema":{"title":"X-API-Key","type":"string","description":"API key authentication. Send the key in the X-API-Key header; keys are prefixed with 'comfyui-' and are generated from user account settings. The same 'comfyui-' key is also accepted in Authorization: Bearer (see BearerAuth), and when both headers carry a key, X-API-Key wins.","isRequired":true,"typeLabel":"string","deprecated":false},"schemeName":"ApiKeyAuth","name":"X-API-Key"}],"title":"ApiKeyAuth"}]},"originalFileLocation":"router-openapi.yaml"},"subdomain":"dripart","siteName":"ComfyUI","title":"Read one partner model's catalog entry by canonical model ID. - ComfyUI","navMaps":{"firstHrefInVersion":{},"firstHrefInLanguage":{"en":{"href":"/api-reference/router/comfy-router/read-one-partner-models-catalog-entry-by-canonical-model-id","matchLevel":1},"zh":{"href":"/zh/api-reference/router/comfy-router/read-one-partner-models-catalog-entry-by-canonical-model-id","matchLevel":1},"ja":{"href":"/ja/api-reference/router/comfy-router/read-one-partner-models-catalog-entry-by-canonical-model-id","matchLevel":1},"ko":{"href":"/ko/api-reference/router/comfy-router/read-one-partner-models-catalog-entry-by-canonical-model-id","matchLevel":0},"es":{"href":"/es/api-reference/router/comfy-router/read-one-partner-models-catalog-entry-by-canonical-model-id","matchLevel":1}}},"lastModified":"2026-11-09T12:33:51.932Z","originalFileLocation":"ko/api-reference/router/comfy-router/read-one-partner-models-catalog-entry-by-canonical-model-id.mdx","locale":"ko"},"headHtml":"\u003cscript data-mint-head>(function(){var d=document.documentElement,p=null;if(!p){try{p=localStorage.getItem(\"isDarkMode\")}catch(e){}if(p==='true')p='dark';else if(p==='false')p='light';if(p!=='light'\u0026\u0026p!=='dark'\u0026\u0026p!=='system')p=\"dark\"}var r=p==='system'?(matchMedia(\"(prefers-color-scheme: dark)\").matches?'dark':'light'):p;d.classList.remove(r==='dark'?'light':'dark');d.classList.add(r);d.setAttribute(\"data-theme-preference\",p)})();\u003c/script>\u003cmeta data-mint-head name=\"description\" content=\"Per-model detail for a single Comfy Router model, so a caller can check one model without walking the whole paginated catalog. The SDKs use it to look a model up immediately before invoking it.\">\u003cmeta data-mint-head name=\"application-name\" content=\"ComfyUI\">\u003cmeta data-mint-head name=\"generator\" content=\"Mintlify\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"192x192\" href=\"/mintlify-assets/_mintlify/favicons/dripart/lS3H5I41bE6LSXEf/_generated/favicon/android-chrome-192x192.png\" media=\"(prefers-color-scheme: light)\">\u003clink data-mint-head rel=\"apple-touch-icon\" type=\"image/png\" sizes=\"180x180\" href=\"/mintlify-assets/_mintlify/favicons/dripart/lS3H5I41bE6LSXEf/_generated/favicon/apple-touch-icon.png\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"16x16\" href=\"/mintlify-assets/_mintlify/favicons/dripart/lS3H5I41bE6LSXEf/_generated/favicon/favicon-16x16.png\" media=\"(prefers-color-scheme: light)\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"32x32\" href=\"/mintlify-assets/_mintlify/favicons/dripart/lS3H5I41bE6LSXEf/_generated/favicon/favicon-32x32.png\" media=\"(prefers-color-scheme: light)\">\u003clink data-mint-head rel=\"shortcut icon\" type=\"image/x-icon\" href=\"/mintlify-assets/_mintlify/favicons/dripart/lS3H5I41bE6LSXEf/_generated/favicon/favicon.ico\" media=\"(prefers-color-scheme: light)\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"192x192\" href=\"/mintlify-assets/_mintlify/favicons/dripart/lS3H5I41bE6LSXEf/_generated/favicon-dark/android-chrome-192x192.png\" media=\"(prefers-color-scheme: dark)\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"16x16\" href=\"/mintlify-assets/_mintlify/favicons/dripart/lS3H5I41bE6LSXEf/_generated/favicon-dark/favicon-16x16.png\" media=\"(prefers-color-scheme: dark)\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"32x32\" href=\"/mintlify-assets/_mintlify/favicons/dripart/lS3H5I41bE6LSXEf/_generated/favicon-dark/favicon-32x32.png\" media=\"(prefers-color-scheme: dark)\">\u003clink data-mint-head rel=\"shortcut icon\" type=\"image/x-icon\" href=\"/mintlify-assets/_mintlify/favicons/dripart/lS3H5I41bE6LSXEf/_generated/favicon-dark/favicon.ico\" media=\"(prefers-color-scheme: dark)\">\u003cmeta data-mint-head property=\"og:title\" content=\"Read one partner model\u0026#x27;s catalog entry by canonical model ID. - ComfyUI\">\u003cmeta data-mint-head property=\"og:description\" content=\"Per-model detail for a single Comfy Router model, so a caller can check one model without walking the whole paginated catalog. The SDKs use it to look a model up immediately before invoking it.\">\u003cmeta data-mint-head property=\"og:site_name\" content=\"ComfyUI\">\u003cmeta data-mint-head property=\"og:url\" content=\"https://docs.comfy.org/ko/api-reference/router/comfy-router/read-one-partner-models-catalog-entry-by-canonical-model-id\">\u003cmeta data-mint-head property=\"og:type\" content=\"website\">\u003cmeta data-mint-head property=\"og:image\" content=\"https://dripart.mintlify.site/_mintlify/api/og/v2?division=Comfy+Router\u0026amp;title=Read+one+partner+model%27s+catalog+entry+by+canonical+model+ID.\u0026amp;description=Per-model+detail+for+a+single+Comfy+Router+model%2C+so+a+caller+can+check+one+model+without+walking+the+whole+paginated+catalog.+The+SDKs+use+it+to+look+a+model+u\u0026amp;theme=b252c39adf72ba65053766a0\u0026amp;signature=2cb07b4ed74741149bdebf7fa66b2a368baa3be95a0412c13800edea2d32674d\">\u003cmeta data-mint-head property=\"og:image:width\" content=\"1200\">\u003cmeta data-mint-head property=\"og:image:height\" content=\"630\">\u003cmeta data-mint-head name=\"twitter:card\" content=\"summary_large_image\">\u003cmeta data-mint-head name=\"twitter:title\" content=\"Read one partner model\u0026#x27;s catalog entry by canonical model ID. - ComfyUI\">\u003cmeta data-mint-head name=\"twitter:description\" content=\"Per-model detail for a single Comfy Router model, so a caller can check one model without walking the whole paginated catalog. The SDKs use it to look a model up immediately before invoking it.\">\u003cmeta data-mint-head name=\"twitter:image\" content=\"https://dripart.mintlify.site/_mintlify/api/og/v2?division=Comfy+Router\u0026amp;title=Read+one+partner+model%27s+catalog+entry+by+canonical+model+ID.\u0026amp;description=Per-model+detail+for+a+single+Comfy+Router+model%2C+so+a+caller+can+check+one+model+without+walking+the+whole+paginated+catalog.+The+SDKs+use+it+to+look+a+model+u\u0026amp;theme=b252c39adf72ba65053766a0\u0026amp;signature=2cb07b4ed74741149bdebf7fa66b2a368baa3be95a0412c13800edea2d32674d\">\u003cmeta data-mint-head name=\"twitter:image:width\" content=\"1200\">\u003cmeta data-mint-head name=\"twitter:image:height\" content=\"630\">\u003cmeta data-mint-head name=\"msapplication-config\" content=\"/mintlify-assets/_mintlify/favicons/dripart/lS3H5I41bE6LSXEf/_generated/favicon/browserconfig.xml\">\u003cmeta data-mint-head name=\"apple-mobile-web-app-title\" content=\"ComfyUI\">\u003cmeta data-mint-head name=\"msapplication-TileColor\" content=\"#49378B\">\u003cmeta data-mint-head name=\"googlebot\" content=\"max-video-preview:0\">\u003clink data-mint-head rel=\"canonical\" href=\"https://docs.comfy.org/ko/api-reference/router/comfy-router/read-one-partner-models-catalog-entry-by-canonical-model-id\">\u003clink data-mint-head rel=\"alternate\" type=\"application/xml\" href=\"/sitemap.xml\">\u003clink data-mint-head rel=\"alternate\" type=\"text/markdown\" href=\"/ko/api-reference/router/comfy-router/read-one-partner-models-catalog-entry-by-canonical-model-id.md\">\u003clink data-mint-head rel=\"alternate\" hreflang=\"ko\" href=\"https://docs.comfy.org/ko/api-reference/router/comfy-router/read-one-partner-models-catalog-entry-by-canonical-model-id\">\u003clink data-mint-head rel=\"alternate\" hreflang=\"en\" href=\"https://docs.comfy.org/api-reference/router/comfy-router/read-one-partner-models-catalog-entry-by-canonical-model-id\">\u003clink data-mint-head rel=\"alternate\" hreflang=\"zh\" href=\"https://docs.comfy.org/zh/api-reference/router/comfy-router/read-one-partner-models-catalog-entry-by-canonical-model-id\">\u003clink data-mint-head rel=\"alternate\" hreflang=\"ja\" href=\"https://docs.comfy.org/ja/api-reference/router/comfy-router/read-one-partner-models-catalog-entry-by-canonical-model-id\">\u003clink data-mint-head rel=\"alternate\" hreflang=\"es\" href=\"https://docs.comfy.org/es/api-reference/router/comfy-router/read-one-partner-models-catalog-entry-by-canonical-model-id\">\u003clink data-mint-head rel=\"alternate\" hreflang=\"x-default\" href=\"https://docs.comfy.org/api-reference/router/comfy-router/read-one-partner-models-catalog-entry-by-canonical-model-id\">\u003cscript data-mint-head type=\"application/ld+json\">{\"@context\":\"https://schema.org\",\"@graph\":[{\"@type\":\"Organization\",\"@id\":\"https://docs.comfy.org/#organization\",\"name\":\"ComfyUI\",\"url\":\"https://docs.comfy.org\",\"logo\":{\"@type\":\"ImageObject\",\"url\":\"https://mintcdn.com/dripart/WCFdTagRdhtvk9-o/logo/light.svg?fit=max\u0026auto=format\u0026n=WCFdTagRdhtvk9-o\u0026q=85\u0026s=ec112de87239058f5a931a7e4b594965\"}},{\"@type\":\"WebSite\",\"@id\":\"https://docs.comfy.org#website\",\"name\":\"ComfyUI\",\"url\":\"https://docs.comfy.org\",\"publisher\":{\"@id\":\"https://docs.comfy.org/#organization\"}},{\"@type\":\"WebPage\",\"@id\":\"https://docs.comfy.org/ko/api-reference/router/comfy-router/read-one-partner-models-catalog-entry-by-canonical-model-id#webpage\",\"url\":\"https://docs.comfy.org/ko/api-reference/router/comfy-router/read-one-partner-models-catalog-entry-by-canonical-model-id\",\"name\":\"Read one partner model's catalog entry by canonical model ID.\",\"description\":\"Per-model detail for a single Comfy Router model, so a caller can check one model without walking the whole paginated catalog. The SDKs use it to look a model up immediately before invoking it.\",\"dateModified\":\"2026-11-09T12:33:51.932Z\",\"isPartOf\":{\"@id\":\"https://docs.comfy.org#website\"},\"breadcrumb\":{\"@id\":\"https://docs.comfy.org/ko/api-reference/router/comfy-router/read-one-partner-models-catalog-entry-by-canonical-model-id#breadcrumb\"}},{\"@type\":\"BreadcrumbList\",\"@id\":\"https://docs.comfy.org/ko/api-reference/router/comfy-router/read-one-partner-models-catalog-entry-by-canonical-model-id#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Comfy Router\",\"item\":\"https://docs.comfy.org/ko/development/comfy-router/quickstart\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Comfy Router API 참조\",\"item\":\"https://docs.comfy.org/ko/api-reference/router/comfy-router/list-the-models-comfy-router-can-run\"},{\"@type\":\"ListItem\",\"position\":3,\"name\":\"Comfy Router\",\"item\":\"https://docs.comfy.org/ko/api-reference/router/comfy-router/list-the-models-comfy-router-can-run\"},{\"@type\":\"ListItem\",\"position\":4,\"name\":\"Read one partner model's catalog entry by canonical model ID.\",\"item\":\"https://docs.comfy.org/ko/api-reference/router/comfy-router/read-one-partner-models-catalog-entry-by-canonical-model-id\"}]},{\"@type\":[\"TechArticle\",\"APIReference\"],\"@id\":\"https://docs.comfy.org/ko/api-reference/router/comfy-router/read-one-partner-models-catalog-entry-by-canonical-model-id#apireference\",\"headline\":\"Read one partner model's catalog entry by canonical model ID.\",\"name\":\"Read one partner model's catalog entry by canonical model ID.\",\"description\":\"Per-model detail for a single Comfy Router model, so a caller can check one model without walking the whole paginated catalog. The SDKs use it to look a model up immediately before invoking it.\",\"url\":\"https://docs.comfy.org/ko/api-reference/router/comfy-router/read-one-partner-models-catalog-entry-by-canonical-model-id\",\"mainEntityOfPage\":{\"@id\":\"https://docs.comfy.org/ko/api-reference/router/comfy-router/read-one-partner-models-catalog-entry-by-canonical-model-id#webpage\"},\"dateModified\":\"2026-11-09T12:33:51.932Z\",\"publisher\":{\"@id\":\"https://docs.comfy.org/#organization\"},\"isPartOf\":{\"@id\":\"https://docs.comfy.org#website\"}}]}\u003c/script>\u003cscript data-mint-head type=\"application/ld+json\">{\"@context\":\"https://schema.org\",\"@type\":\"WebSite\",\"name\":\"ComfyUI\",\"creator\":{\"@type\":\"Organization\",\"name\":\"Mintlify\",\"url\":\"https://mintlify.com\"}}\u003c/script>","siteName":"ComfyUI","nav":{"global":null,"languages":[{"language":"en","pages":[{"title":"en","href":"/api-reference/router/comfy-router/read-one-partner-models-catalog-entry-by-canonical-model-id"}]},{"language":"zh","footer":{"socials":{"github":"https://github.com/Comfy-Org/ComfyUI","x":"https://x.com/ComfyUI","discord":"https://discord.com/invite/comfyorg","youtube":"https://www.youtube.com/@comfyorg"},"links":[{"header":"资源","items":[{"label":"安装","href":"/zh/installation/system_requirements"},{"label":"教程","href":"/zh/tutorials/basic/text-to-image"},{"label":"开发","href":"/zh/development/overview"}]},{"header":"产品","items":[{"label":"功能","href":"https://www.comfy.org/?utm_source=docs"},{"label":"画廊","href":"https://www.comfy.org/gallery?utm_source=docs"},{"label":"下载","href":"https://www.comfy.org/download?utm_source=docs"}]},{"header":"公司","items":[{"label":"关于","href":"https://www.comfy.org/about?utm_source=docs"},{"label":"招聘","href":"https://www.comfy.org/careers?utm_source=docs"},{"label":"服务条款","href":"https://www.comfy.org/terms-of-service?utm_source=docs"},{"label":"隐私政策","href":"https://www.comfy.org/privacy-policy?utm_source=docs"}]}]},"pages":[{"title":"zh","href":"/zh/api-reference/router/comfy-router/read-one-partner-models-catalog-entry-by-canonical-model-id"}]},{"language":"ja","footer":{"socials":{"github":"https://github.com/Comfy-Org/ComfyUI","x":"https://x.com/ComfyUI","discord":"https://discord.com/invite/comfyorg","youtube":"https://www.youtube.com/@comfyorg"},"links":[{"header":"リソース","items":[{"label":"インストール","href":"/ja/installation/system_requirements"},{"label":"チュートリアル","href":"/ja/tutorials/basic/text-to-image"},{"label":"開発","href":"/ja/development/overview"}]},{"header":"プロダクト","items":[{"label":"機能","href":"https://www.comfy.org/?utm_source=docs"},{"label":"ギャラリー","href":"https://www.comfy.org/gallery?utm_source=docs"},{"label":"ダウンロード","href":"https://www.comfy.org/download?utm_source=docs"}]},{"header":"会社情報","items":[{"label":"概要","href":"https://www.comfy.org/about?utm_source=docs"},{"label":"採用情報","href":"https://www.comfy.org/careers?utm_source=docs"},{"label":"利用規約","href":"https://www.comfy.org/terms-of-service?utm_source=docs"},{"label":"プライバシーポリシー","href":"https://www.comfy.org/privacy-policy?utm_source=docs"}]}]},"navbar":{"links":[{"href":"/ja/tutorials/partner-nodes/pricing","label":"料金"},{"href":"https://comfy.org/download?utm_source=docs","label":"ダウンロード"}],"primary":{"type":"button","label":"Comfy Cloud","href":"https://comfy.org/cloud?utm_source=docs"}},"pages":[{"title":"ja","href":"/ja/api-reference/router/comfy-router/read-one-partner-models-catalog-entry-by-canonical-model-id"}]},{"language":"ko","footer":{"socials":{"github":"https://github.com/Comfy-Org/ComfyUI","x":"https://x.com/ComfyUI","discord":"https://discord.com/invite/comfyorg","youtube":"https://www.youtube.com/@comfyorg"},"links":[{"header":"리소스","items":[{"label":"설치","href":"/ko/installation/system_requirements"},{"label":"튜토리얼","href":"/ko/tutorials/basic/text-to-image"},{"label":"개발","href":"/ko/development/overview"}]},{"header":"제품","items":[{"label":"기능","href":"https://www.comfy.org/?utm_source=docs"},{"label":"갤러리","href":"https://www.comfy.org/gallery?utm_source=docs"},{"label":"다운로드","href":"https://www.comfy.org/download?utm_source=docs"}]},{"header":"회사 정보","items":[{"label":"소개","href":"https://www.comfy.org/about?utm_source=docs"},{"label":"채용","href":"https://www.comfy.org/careers?utm_source=docs"},{"label":"이용약관","href":"https://www.comfy.org/terms-of-service?utm_source=docs"},{"label":"개인정보 처리방침","href":"https://www.comfy.org/privacy-policy?utm_source=docs"}]}]},"navbar":{"links":[{"href":"/ko/tutorials/partner-nodes/pricing","label":"가격 정책"},{"href":"https://comfy.org/download?utm_source=docs","label":"다운로드"}],"primary":{"type":"button","label":"Comfy Cloud","href":"https://comfy.org/cloud?utm_source=docs"}},"tabs":[{"tab":"시작하기","pages":[{"title":"시작하기","href":"/ko"}]},{"tab":"내장 노드 (Built-in Nodes)","pages":[{"title":"내장 노드 (Built-in Nodes)","href":"/ko/built-in-nodes/overview"}]},{"tab":"API 개발","pages":[{"group":"Comfy로 개발하기","pages":[{"title":"개발자를 위한 ComfyUI: SDK, 서버 API 및 클라우드","sidebarTitle":"개발자 개요","href":"/ko/development/overview"},{"group":"Comfy Cloud","pages":[{"title":"v1 Cloud API 개요","sidebarTitle":"개요","href":"/ko/development/cloud/overview"},{"title":"클라우드 API 참조","icon":"book-open","href":"/ko/development/cloud/api-reference"},{"title":"OpenAPI 사양","icon":"file-lines","openapi":"/openapi-cloud.yaml","href":"/ko/development/cloud/openapi"}]},{"group":"자체 호스팅 서버","pages":[{"title":"서버 개요","sidebarTitle":"서버 개요","href":"/ko/development/comfyui-server/comms_overview"},{"title":"ComfyUI Server API 예제: HTTP, WebSocket, 기록","sidebarTitle":"API 예제","href":"/ko/development/comfyui-server/api-examples"},{"title":"ComfyUI 서버 경로 (HTTP 및 WebSocket API)","sidebarTitle":"HTTP 및 WebSocket 라우트","href":"/ko/development/comfyui-server/comms_routes"},{"title":"ComfyUI 서버 메시지 (WebSocket API)","sidebarTitle":"WebSocket 메시지","icon":"comment","href":"/ko/development/comfyui-server/comms_messages"},{"title":"ComfyUI 시작 플래그: 명령줄 레퍼런스","sidebarTitle":"시작 플래그","icon":"terminal","href":"/ko/development/comfyui-server/startup-flags"},{"title":"셀프 호스팅 옵션","sidebarTitle":"호스팅 옵션","icon":"server","href":"/ko/development/deploy/self-hosting"}]},{"title":"ComfyUI 배포하기","sidebarTitle":"개요","icon":"map","href":"/ko/development/deploy/overview"},{"title":"Comfy Cloud 빠른 시작","sidebarTitle":"빠른 시작","icon":"cloud","href":"/ko/development/deploy/cloud"},{"title":"Comfy API 및 Router 예제","sidebarTitle":"예제","icon":"code","mode":"wide","href":"/ko/development/examples"}]},{"group":"워크플로 실행","pages":[{"title":"워크플로 실행","sidebarTitle":"개요","icon":"play","href":"/ko/development/run-workflows/overview"},{"title":"첫 워크플로 실행하기","sidebarTitle":"첫 워크플로","href":"/ko/development/api-development/quickstart"},{"title":"Comfy SDK: ComfyUI용 Python 및 TypeScript 클라이언트","sidebarTitle":"SDK","icon":"code","href":"/ko/development/api-development/sdks"},{"title":"자체 호스팅 ComfyUI를 위한 API 프록시","sidebarTitle":"API 프록시","icon":"plug","href":"/ko/development/comfyui-server/api-proxy"},{"title":"Comfy API: 서버리스 배포","icon":"cloud-arrow-up","href":"/ko/development/serverless/overview"},{"title":"API 키 받기","sidebarTitle":"API 키","icon":"key","href":"/ko/development/api-development/getting-an-api-key"},{"title":"Comfy API v2 개요","sidebarTitle":"Overview","href":"/ko/api-reference/v2/overview"},{"group":"Comfy API v2 참조","pages":[{"group":"assets","pages":[{"title":"Upload an asset (single-call multipart)","deprecated":null,"version":null,"openapi":"/openapi-v2.yaml post /api/v2/assets","href":"/ko/api-reference/v2/assets/upload-an-asset-single-call-multipart"},{"title":"Create or reuse an asset over existing bytes","deprecated":null,"version":null,"openapi":"/openapi-v2.yaml post /api/v2/assets/from-hash","href":"/ko/api-reference/v2/assets/create-or-reuse-an-asset-over-existing-bytes"},{"title":"Existence check for a blob by blake3 hash","deprecated":null,"version":null,"openapi":"/openapi-v2.yaml head /api/v2/assets/by-hash/{hash}","href":"/ko/api-reference/v2/assets/existence-check-for-a-blob-by-blake3-hash"},{"title":"Asset metadata","deprecated":null,"version":null,"openapi":"/openapi-v2.yaml get /api/v2/assets/{id}","href":"/ko/api-reference/v2/assets/asset-metadata"},{"title":"Delete an asset record","deprecated":null,"version":null,"openapi":"/openapi-v2.yaml delete /api/v2/assets/{id}","href":"/ko/api-reference/v2/assets/delete-an-asset-record"},{"title":"Asset bytes","deprecated":null,"version":null,"openapi":"/openapi-v2.yaml get /api/v2/assets/{id}/content","href":"/ko/api-reference/v2/assets/asset-bytes"}]},{"group":"jobs","pages":[{"title":"List jobs, newest first","deprecated":null,"version":null,"openapi":"/openapi-v2.yaml get /api/v2/jobs","href":"/ko/api-reference/v2/jobs/list-jobs-newest-first"},{"title":"Submit a workflow for execution","deprecated":null,"version":null,"openapi":"/openapi-v2.yaml post /api/v2/jobs","href":"/ko/api-reference/v2/jobs/submit-a-workflow-for-execution"},{"title":"Job status (the polling workhorse)","deprecated":null,"version":null,"openapi":"/openapi-v2.yaml get /api/v2/jobs/{id}","href":"/ko/api-reference/v2/jobs/job-status-the-polling-workhorse"},{"title":"The workflow behind a job — authoring version if pinned, executed graph otherwise","deprecated":null,"version":null,"openapi":"/openapi-v2.yaml get /api/v2/jobs/{id}/workflow","href":"/ko/api-reference/v2/jobs/the-workflow-behind-a-job-—-authoring-version-if-pinned-executed-graph-otherwise"},{"title":"What the run printed","deprecated":null,"version":null,"openapi":"/openapi-v2.yaml get /api/v2/jobs/{id}/logs","href":"/ko/api-reference/v2/jobs/what-the-run-printed"},{"title":"Live event stream (SSE)","deprecated":null,"version":null,"openapi":"/openapi-v2.yaml get /api/v2/jobs/{id}/events","href":"/ko/api-reference/v2/jobs/live-event-stream-sse"},{"title":"Request cancellation","deprecated":null,"version":null,"openapi":"/openapi-v2.yaml post /api/v2/jobs/{id}/cancel","href":"/ko/api-reference/v2/jobs/request-cancellation"}]}]},{"title":"디자인 노트","sidebarTitle":"디자인 노트","icon":"compass","href":"/ko/development/api-development/sdks-design"},{"title":"워크플로 API 형식","icon":"file-code","href":"/ko/development/api-development/workflow-api-format"},{"title":"워크플로 메타데이터: ComfyUI 출력 파일에 포함되는 워크플로","sidebarTitle":"워크플로 메타데이터","icon":"file-code","href":"/ko/development/api-development/workflow-metadata"},{"title":"ComfyUI 계정 API 키 통합","sidebarTitle":"API 키 연동","icon":"puzzle-piece","href":"/ko/development/comfyui-server/api-key-integration"},{"group":"Comfy API Reference","pages":[{"title":"Comfy API 버전: v2 및 지원 중단된 v1 Cloud API","sidebarTitle":"개요","href":"/ko/development/comfy-api/overview"}]}]},{"group":"Comfy Router","pages":[{"title":"Comfy Router 빠른 시작","sidebarTitle":"빠른 시작","href":"/ko/development/comfy-router/quickstart"},{"title":"Comfy Router API 개요","sidebarTitle":"개요","href":"/ko/development/comfy-router/api"},{"title":"Comfy Router 모델 찾아보기","sidebarTitle":"모델 찾아보기","href":"/ko/development/comfy-router/discover-models"},{"title":"Comfy Router 모델 스키마와 결과","sidebarTitle":"스키마와 결과","href":"/ko/development/comfy-router/schemas"},{"title":"Comfy Router 요청을 대기열에 넣기","sidebarTitle":"대기 중인 요청","href":"/ko/development/comfy-router/queue"},{"title":"Comfy Router 오류 및 재시도","sidebarTitle":"오류 및 재시도","href":"/ko/development/comfy-router/errors"},{"title":"Comfy Router 청구","sidebarTitle":"청구","href":"/ko/development/comfy-router/billing"},{"title":"LiteLLM과 함께 Comfy Router 사용하기","sidebarTitle":"LiteLLM","href":"/ko/development/comfy-router/litellm"},{"title":"Comfy Router 실시간 음성 세션","sidebarTitle":"실시간 음성","href":"/ko/development/comfy-router/realtime"},{"title":"Comfy Router 헤더","sidebarTitle":"헤더","href":"/ko/development/comfy-router/headers"},{"title":"Comfy Router API 레퍼런스","sidebarTitle":"API 레퍼런스","href":"/ko/development/comfy-router/reference"},{"title":"Comfy Router 기능과 한계","sidebarTitle":"기능과 한계","href":"/ko/development/comfy-router/limitations"},{"group":"Comfy Router API 참조","pages":[{"group":"Comfy Router","pages":[{"title":"List the models Comfy Router can run.","description":"Comfy Router's model catalog - one page of the canonical model IDs that `POST /v2/models/{provider}/{model}` accepts. An SDK calls this on cold start to discover what is runnable, and the `model_not_found` suggestions come from the same catalog, so an ID listed here that then 404s on invocation would be worse than either failure alone. That agreement is structural rather than a promise: an entry's `provider` and `model` are the two path segments of the invocation route and reference the same schema components that route's path parameters do, and `id` is those two segments joined by `/`.","deprecated":null,"version":null,"openapi":"/router-openapi.yaml get /v2/models","href":"/ko/api-reference/router/comfy-router/list-the-models-comfy-router-can-run"},{"title":"Read one partner model's catalog entry by canonical model ID.","deprecated":null,"version":null,"openapi":"/router-openapi.yaml get /v2/models/{provider}/{model}","href":"/ko/api-reference/router/comfy-router/read-one-partner-models-catalog-entry-by-canonical-model-id"},{"title":"Run a partner model synchronously by canonical model ID.","description":"Comfy Router's canonical, model-ID-addressed entry point. The request body is the partner model's own native JSON input and the success response is that model's own native output — JSON for most models, but the partner's raw bytes (for example `audio/mpeg` for a text-to-speech model) for a model whose partner answers with a binary body: Router forwards both without imposing a Comfy-shaped envelope, so for most models a caller can move between the partner's API and Router by changing the host. The exception is a model whose partner operation takes an identifier in its request path: Router has the caller name it as a top-level body field and moves it into the partner path, so that request needs that one adaptation. This is the synchronous path: the response carries the finished result.","deprecated":null,"version":null,"openapi":"/router-openapi.yaml post /v2/models/{provider}/{model}","href":"/ko/api-reference/router/comfy-router/run-a-partner-model-synchronously-by-canonical-model-id"},{"title":"Price a model call before running it, without running it.","deprecated":null,"version":null,"openapi":"/router-openapi.yaml post /v2/models/{provider}/{model}/estimate","href":"/ko/api-reference/router/comfy-router/price-a-model-call-before-running-it-without-running-it"},{"title":"Read one partner model's input and output schemas as an OpenAPI document.","deprecated":null,"version":null,"openapi":"/router-openapi.yaml get /v2/models/{provider}/{model}/openapi.json","href":"/ko/api-reference/router/comfy-router/read-one-partner-models-input-and-output-schemas-as-an-openapi-document"},{"title":"Submit a partner model run to the queue and return immediately.","deprecated":null,"version":null,"openapi":"/router-openapi.yaml post /v2/models/{provider}/{model}/requests","href":"/ko/api-reference/router/comfy-router/submit-a-partner-model-run-to-the-queue-and-return-immediately"},{"title":"Collect the result of one submitted request.","deprecated":null,"version":null,"openapi":"/router-openapi.yaml get /v2/models/{provider}/{model}/requests/{request_id}","href":"/ko/api-reference/router/comfy-router/collect-the-result-of-one-submitted-request"},{"title":"Ask for one submitted request to be cancelled.","deprecated":null,"version":null,"openapi":"/router-openapi.yaml put /v2/models/{provider}/{model}/requests/{request_id}/cancel","href":"/ko/api-reference/router/comfy-router/ask-for-one-submitted-request-to-be-cancelled"},{"title":"Read the queue state of one submitted request.","deprecated":null,"version":null,"openapi":"/router-openapi.yaml get /v2/models/{provider}/{model}/requests/{request_id}/status","href":"/ko/api-reference/router/comfy-router/read-the-queue-state-of-one-submitted-request"}]}]},{"group":"Models","pages":[{"title":"Comfy Router 모델","sidebarTitle":"모든 모델","href":"/ko/development/comfy-router/models"},{"title":"Comfy Router 요금","sidebarTitle":"요금","mode":"wide","href":"/ko/development/comfy-router/pricing"},{"title":"Comfy Router 서빙 공급자","sidebarTitle":"서빙 공급자","href":"/ko/development/comfy-router/providers"},{"group":"Anthropic","pages":[{"title":"Comfy Router에서 Claude Fable 5.1 사용하기","sidebarTitle":"Claude Fable 5.1","href":"/ko/development/comfy-router/models/anthropic/claude-fable-5-1/code"},{"title":"Comfy Router로 Claude Fable 5 사용하기","sidebarTitle":"Claude Fable 5","href":"/ko/development/comfy-router/models/anthropic/claude-fable-5/code"},{"title":"Comfy Router로 Claude Haiku 4.5 20251001 사용하기","sidebarTitle":"Claude Haiku 4.5 20251001","href":"/ko/development/comfy-router/models/anthropic/claude-haiku-4-5-20251001/code"},{"title":"Comfy Router와 함께 Claude Opus 4.6 사용하기","sidebarTitle":"Claude Opus 4.6","href":"/ko/development/comfy-router/models/anthropic/claude-opus-4-6/code"},{"title":"Comfy Router와 함께 Claude Opus 4.7 사용하기","sidebarTitle":"Claude Opus 4.7","href":"/ko/development/comfy-router/models/anthropic/claude-opus-4-7/code"},{"title":"Comfy Router에서 Claude Opus 4.8 사용하기","sidebarTitle":"Claude Opus 4.8","href":"/ko/development/comfy-router/models/anthropic/claude-opus-4-8/code"},{"title":"Comfy Router에서 Claude Opus 5.5 사용하기","sidebarTitle":"Claude Opus 5.5","href":"/ko/development/comfy-router/models/anthropic/claude-opus-5-5/code"},{"title":"Comfy Router로 Claude Opus 5 사용하기","sidebarTitle":"Claude Opus 5","href":"/ko/development/comfy-router/models/anthropic/claude-opus-5/code"},{"title":"Comfy Router로 Claude Sonnet 4.5 20250929 사용하기","sidebarTitle":"Claude Sonnet 4.5 20250929","href":"/ko/development/comfy-router/models/anthropic/claude-sonnet-4-5-20250929/code"},{"title":"Comfy Router로 Claude Sonnet 4.6 사용하기","sidebarTitle":"Claude Sonnet 4.6","href":"/ko/development/comfy-router/models/anthropic/claude-sonnet-4-6/code"},{"title":"Comfy Router로 Claude Sonnet 5.5 사용하기","sidebarTitle":"Claude Sonnet 5.5","href":"/ko/development/comfy-router/models/anthropic/claude-sonnet-5-5/code"},{"title":"Comfy Router에서 Claude Sonnet 5 사용하기","sidebarTitle":"Claude Sonnet 5","href":"/ko/development/comfy-router/models/anthropic/claude-sonnet-5/code"}]},{"group":"Beeble","pages":[{"title":"Comfy Router로 SwitchX 사용하기","sidebarTitle":"SwitchX","href":"/ko/development/comfy-router/models/beeble/switchx/code"}]},{"group":"Black Forest Labs","pages":[{"title":"Comfy Router에서 Erase V1 사용하기","sidebarTitle":"Erase V1","href":"/ko/development/comfy-router/models/black-forest-labs/erase-v1/code"},{"title":"Comfy Router로 Flux 1.1 Pro Ultra 이미지 사용하기","sidebarTitle":"Flux 1.1 Pro Ultra 이미지","href":"/ko/development/comfy-router/models/black-forest-labs/flux-1-1-pro-ultra-image/code"},{"title":"Comfy Router로 FLUX.1 Kontext 사용하기","sidebarTitle":"FLUX.1 Kontext","href":"/ko/development/comfy-router/models/black-forest-labs/flux-1-kontext/code"},{"title":"Comfy Router로 FLUX 2 Max 사용하기","sidebarTitle":"FLUX 2 Max","href":"/ko/development/comfy-router/models/black-forest-labs/flux-2-max/code"},{"title":"Comfy Router로 FLUX 2 Pro 사용하기","sidebarTitle":"FLUX 2 Pro","href":"/ko/development/comfy-router/models/black-forest-labs/flux-2-pro/code"},{"title":"Comfy Router로 FLUX 3 Image 사용하기","sidebarTitle":"FLUX 3 Image","href":"/ko/development/comfy-router/models/black-forest-labs/flux-3-image/code"},{"title":"Comfy Router로 FLUX 3 Video 사용하기","sidebarTitle":"FLUX 3 Video","href":"/ko/development/comfy-router/models/black-forest-labs/flux-3-video/code"},{"title":"Comfy Router로 FLUX Pro 1.0 Expand 사용하기","sidebarTitle":"FLUX Pro 1.0 Expand","href":"/ko/development/comfy-router/models/black-forest-labs/flux-pro-1-0-expand/code"},{"title":"Comfy Router와 함께 FLUX Pro 1.0 Fill 사용하기","sidebarTitle":"FLUX Pro 1.0 Fill","href":"/ko/development/comfy-router/models/black-forest-labs/flux-pro-1-0-fill/code"},{"title":"Comfy Router로 FLUX Video Upscale 사용하기","sidebarTitle":"FLUX Video Upscale","href":"/ko/development/comfy-router/models/black-forest-labs/flux-video-upscale/code"},{"title":"Comfy Router로 Video Edit V1 사용하기","sidebarTitle":"Video Edit V1","href":"/ko/development/comfy-router/models/black-forest-labs/video-edit-v1/code"},{"title":"Comfy Router로 VTO V1 사용하기","sidebarTitle":"VTO V1","href":"/ko/development/comfy-router/models/black-forest-labs/vto-v1/code"}]},{"group":"Bria","pages":[{"title":"Comfy Router와 함께 Fibo 사용하기","sidebarTitle":"Fibo","href":"/ko/development/comfy-router/models/bria/fibo/code"},{"title":"Comfy Router로 Image Edit Add Object By Text 사용하기","sidebarTitle":"Image Edit Add Object By Text","href":"/ko/development/comfy-router/models/bria/image-edit-add-object-by-text/code"},{"title":"Comfy Router로 Image Edit Erase By Text 사용하기","sidebarTitle":"Image Edit Erase By Text","href":"/ko/development/comfy-router/models/bria/image-edit-erase-by-text/code"},{"title":"Comfy Router로 Image Edit Erase Foreground 사용하기","sidebarTitle":"Image Edit Erase Foreground","href":"/ko/development/comfy-router/models/bria/image-edit-erase-foreground/code"},{"title":"Comfy Router로 Image Edit Erase 사용하기","sidebarTitle":"Image Edit Erase","href":"/ko/development/comfy-router/models/bria/image-edit-erase/code"},{"title":"Comfy Router로 Image Edit Expand 사용하기","sidebarTitle":"Image Edit Expand","href":"/ko/development/comfy-router/models/bria/image-edit-expand/code"},{"title":"Comfy Router로 Image Edit Gen Fill 사용하기","sidebarTitle":"Image Edit Gen Fill","href":"/ko/development/comfy-router/models/bria/image-edit-gen-fill/code"},{"title":"Comfy Router로 Image Edit Increase Resolution 사용하기","sidebarTitle":"Image Edit Increase Resolution","href":"/ko/development/comfy-router/models/bria/image-edit-increase-resolution/code"},{"title":"Comfy Router에서 Image Edit Product Holding 사용하기","sidebarTitle":"Image Edit Product Holding","href":"/ko/development/comfy-router/models/bria/image-edit-product-holding/code"},{"title":"Comfy Router로 Image Edit Product Virtual Tryon 사용하기","sidebarTitle":"Image Edit Product Virtual Tryon","href":"/ko/development/comfy-router/models/bria/image-edit-product-virtual-tryon/code"},{"title":"Comfy Router로 Image Edit Relight 사용하기","sidebarTitle":"Image Edit Relight","href":"/ko/development/comfy-router/models/bria/image-edit-relight/code"},{"title":"Comfy Router로 Image Edit Remove Background Guided 사용하기","sidebarTitle":"Image Edit Remove Background Guided","href":"/ko/development/comfy-router/models/bria/image-edit-remove-background-guided/code"},{"title":"Comfy Router로 Image Edit Remove Background 사용하기","sidebarTitle":"Image Edit Remove Background","href":"/ko/development/comfy-router/models/bria/image-edit-remove-background/code"},{"title":"Comfy Router로 Image Edit Replace Background 사용하기","sidebarTitle":"Image Edit Replace Background","href":"/ko/development/comfy-router/models/bria/image-edit-replace-background/code"},{"title":"Comfy Router로 Image Edit Replace Object By Text 사용하기","sidebarTitle":"Image Edit Replace Object By Text","href":"/ko/development/comfy-router/models/bria/image-edit-replace-object-by-text/code"},{"title":"Comfy Router로 Image Edit Reseason 사용하기","sidebarTitle":"Image Edit Reseason","href":"/ko/development/comfy-router/models/bria/image-edit-reseason/code"},{"title":"Comfy Router로 Image Edit Restore 사용하기","sidebarTitle":"Image Edit Restore","href":"/ko/development/comfy-router/models/bria/image-edit-restore/code"},{"title":"Comfy Router에서 Image 사용하기","sidebarTitle":"Image","href":"/ko/development/comfy-router/models/bria/image/code"},{"title":"Comfy Router로 Video Edit Erase 사용하기","sidebarTitle":"Video Edit Erase","href":"/ko/development/comfy-router/models/bria/video-edit-erase/code"},{"title":"Comfy Router로 Video Edit Green Screen 사용하기","sidebarTitle":"Video Edit Green Screen","href":"/ko/development/comfy-router/models/bria/video-edit-green-screen/code"},{"title":"Comfy Router로 Video Edit Remove Background 사용하기","sidebarTitle":"Video Edit Remove Background","href":"/ko/development/comfy-router/models/bria/video-edit-remove-background/code"},{"title":"Comfy Router로 Video Edit Replace Background 사용하기","sidebarTitle":"Video Edit Replace Background","href":"/ko/development/comfy-router/models/bria/video-edit-replace-background/code"}]},{"group":"BytePlus","pages":[{"title":"Comfy Router로 Dreamina Seedance 2.0 260128 사용하기","sidebarTitle":"Dreamina Seedance 2.0 260128","href":"/ko/development/comfy-router/models/byteplus/dreamina-seedance-2-0-260128/code"},{"title":"Comfy Router로 Dreamina Seedance 2.0 Fast 260128 사용하기","sidebarTitle":"Dreamina Seedance 2.0 Fast 260128","href":"/ko/development/comfy-router/models/byteplus/dreamina-seedance-2-0-fast-260128/code"},{"title":"Comfy Router와 함께 Dreamina Seedance 2.0 Mini 사용하기","sidebarTitle":"Dreamina Seedance 2.0 Mini","href":"/ko/development/comfy-router/models/byteplus/dreamina-seedance-2-0-mini/code"},{"title":"Comfy Router에서 Dreamina Seedance 2.5 260628 사용하기","sidebarTitle":"Dreamina Seedance 2.5 260628","href":"/ko/development/comfy-router/models/byteplus/dreamina-seedance-2-5-260628/code"},{"title":"Comfy Router에서 Seed 2.0 Lite 260228 사용하기","sidebarTitle":"Seed 2.0 Lite 260228","href":"/ko/development/comfy-router/models/byteplus/seed-2-0-lite-260228/code"},{"title":"Comfy Router에서 Seed 2.0 Mini 260215 사용하기","sidebarTitle":"Seed 2.0 Mini 260215","href":"/ko/development/comfy-router/models/byteplus/seed-2-0-mini-260215/code"},{"title":"Comfy Router에서 Seed 2.0 Pro 260328 사용하기","sidebarTitle":"Seed 2.0 Pro 260328","href":"/ko/development/comfy-router/models/byteplus/seed-2-0-pro-260328/code"},{"title":"Comfy Router에서 Seed Audio 1.0 Multilingual 사용하기","sidebarTitle":"Seed Audio 1.0 Multilingual","href":"/ko/development/comfy-router/models/byteplus/seed-audio-1-0-multilingual/code"},{"title":"Comfy Router에서 Seed Audio 1.0 사용하기","sidebarTitle":"Seed Audio 1.0","href":"/ko/development/comfy-router/models/byteplus/seed-audio-1-0/code"},{"title":"Comfy Router로 Seedance 1.0 Pro 250528 사용하기","sidebarTitle":"Seedance 1.0 Pro 250528","href":"/ko/development/comfy-router/models/byteplus/seedance-1-0-pro-250528/code"},{"title":"Comfy Router에서 Seedance 1.0 Pro Fast 251015 사용하기","sidebarTitle":"Seedance 1.0 Pro Fast 251015","href":"/ko/development/comfy-router/models/byteplus/seedance-1-0-pro-fast-251015/code"},{"title":"Comfy Router로 Seedance 1.5 Pro 251215 사용하기","sidebarTitle":"Seedance 1.5 Pro 251215","href":"/ko/development/comfy-router/models/byteplus/seedance-1-5-pro-251215/code"},{"title":"Comfy Router에서 Seedream 4.0 250828 사용하기","sidebarTitle":"Seedream 4.0 250828","href":"/ko/development/comfy-router/models/byteplus/seedream-4-0-250828/code"},{"title":"Comfy Router에서 Seedream 4.5 251128 사용하기","sidebarTitle":"Seedream 4.5 251128","href":"/ko/development/comfy-router/models/byteplus/seedream-4-5-251128/code"},{"title":"Comfy Router로 Seedream 5.0 260128 사용하기","sidebarTitle":"Seedream 5.0 260128","href":"/ko/development/comfy-router/models/byteplus/seedream-5-0-260128/code"},{"title":"Comfy Router로 Seedream 5.0 Flash 260915 사용하기","sidebarTitle":"Seedream 5.0 Flash 260915","href":"/ko/development/comfy-router/models/byteplus/seedream-5-0-flash-260915/code"},{"title":"Comfy Router로 Seedream 5.0 Pro 260628 사용하기","sidebarTitle":"Seedream 5.0 Pro 260628","href":"/ko/development/comfy-router/models/byteplus/seedream-5-0-pro-260628/code"}]},{"group":"Elevenlabs","pages":[{"title":"Comfy Router로 Eleven Multilingual V2 사용하기","sidebarTitle":"Eleven Multilingual V2","href":"/ko/development/comfy-router/models/elevenlabs/eleven-multilingual-v2/code"},{"title":"Comfy Router로 Eleven Sfx V2 사용하기","sidebarTitle":"Eleven Sfx V2","href":"/ko/development/comfy-router/models/elevenlabs/eleven-sfx-v2/code"},{"title":"Comfy Router에서 Eleven V3 사용하기","sidebarTitle":"Eleven V3","href":"/ko/development/comfy-router/models/elevenlabs/eleven-v3/code"},{"title":"Comfy Router와 함께 Eleven V4 Turbo 사용하기","sidebarTitle":"Eleven V4 Turbo","href":"/ko/development/comfy-router/models/elevenlabs/eleven-v4-turbo/code"},{"title":"Comfy Router에서 Eleven V4 사용하기","sidebarTitle":"Eleven V4","href":"/ko/development/comfy-router/models/elevenlabs/eleven-v4/code"}]},{"group":"fal","pages":[{"title":"Comfy Router로 Crystal Upscaler 사용하기","sidebarTitle":"Crystal Upscaler","href":"/ko/development/comfy-router/models/fal/crystal-upscaler/code"},{"title":"Comfy Router로 Crystal Video Upscaler 사용하기","sidebarTitle":"Crystal Video Upscaler","href":"/ko/development/comfy-router/models/fal/crystal-video-upscaler/code"},{"title":"Comfy Router로 FLUX 3 Max 사용하기","sidebarTitle":"FLUX 3 Max","href":"/ko/development/comfy-router/models/fal/flux-3-max/code"},{"title":"Comfy Router로 H3 Max Turbo 사용하기","sidebarTitle":"H3 Max Turbo","href":"/ko/development/comfy-router/models/fal/h3-max-turbo/code"},{"title":"Comfy Router로 H3 Max 사용하기","sidebarTitle":"H3 Max","href":"/ko/development/comfy-router/models/fal/h3-max/code"},{"title":"Comfy Router에서 Patina 사용하기","sidebarTitle":"Patina","href":"/ko/development/comfy-router/models/fal/patina/code"}]},{"group":"Freepik","pages":[{"title":"Comfy Router로 AI Image Upscaler Precision V2 사용하기","sidebarTitle":"AI Image Upscaler Precision V2","href":"/ko/development/comfy-router/models/freepik/ai-image-upscaler-precision-v2/code"},{"title":"Comfy Router로 AI Skin Enhancer Creative 사용하기","sidebarTitle":"AI Skin Enhancer Creative","href":"/ko/development/comfy-router/models/freepik/ai-skin-enhancer-creative/code"},{"title":"Comfy Router로 AI Skin Enhancer Faithful 사용하기","sidebarTitle":"AI Skin Enhancer Faithful","href":"/ko/development/comfy-router/models/freepik/ai-skin-enhancer-faithful/code"},{"title":"Comfy Router로 AI Skin Enhancer Flexible 사용하기","sidebarTitle":"AI Skin Enhancer Flexible","href":"/ko/development/comfy-router/models/freepik/ai-skin-enhancer-flexible/code"}]},{"group":"Gemini Interactions","pages":[{"title":"Comfy Router에서 Gemini Omni 1.1 Flash 사용하기","sidebarTitle":"Gemini Omni 1.1 Flash","href":"/ko/development/comfy-router/models/gemini-interactions/gemini-omni-1-1-flash/code"},{"title":"Comfy Router에서 Gemini Omni 1.2 Flash 사용","sidebarTitle":"Gemini Omni 1.2 Flash","href":"/ko/development/comfy-router/models/gemini-interactions/gemini-omni-1-2-flash/code"},{"title":"Comfy Router와 함께 Gemini Omni Flash Preview 사용하기","sidebarTitle":"Gemini Omni Flash Preview","href":"/ko/development/comfy-router/models/gemini-interactions/gemini-omni-flash-preview/code"}]},{"group":"Google","pages":[{"title":"Comfy Router로 Gemini 2.5 Flash Image 사용하기","sidebarTitle":"Gemini 2.5 Flash Image","href":"/ko/development/comfy-router/models/google/gemini-2-5-flash-image/code"},{"title":"Comfy Router로 Gemini 3.1 Flash Lite 사용하기","sidebarTitle":"Gemini 3.1 Flash Lite","href":"/ko/development/comfy-router/models/google/gemini-3-1-flash-lite/code"},{"title":"Gemini 3.7 Flash를 Comfy Router와 함께 사용하기","sidebarTitle":"Gemini 3.7 Flash","href":"/ko/development/comfy-router/models/google/gemini-3-7-flash/code"},{"title":"Comfy Router로 Gemini 3.8 Flash 사용하기","sidebarTitle":"Gemini 3.8 Flash","href":"/ko/development/comfy-router/models/google/gemini-3-8-flash/code"},{"title":"Comfy Router로 Gemini Nano Banana 2.1 사용하기","sidebarTitle":"Gemini Nano Banana 2.1","href":"/ko/development/comfy-router/models/google/gemini-nano-banana-2-1/code"},{"title":"Comfy Router로 Google Gemini 사용하기","sidebarTitle":"Google Gemini","href":"/ko/development/comfy-router/models/google/gemini/code"},{"title":"Comfy Router로 Nano Banana 2 Lite 사용하기","sidebarTitle":"Nano Banana 2 Lite","href":"/ko/development/comfy-router/models/google/nano-banana-2-lite/code"},{"title":"Comfy Router로 Nano Banana 2 사용하기","sidebarTitle":"Nano Banana 2","href":"/ko/development/comfy-router/models/google/nano-banana-2/code"},{"title":"Comfy Router로 Nano Banana Pro 사용하기","sidebarTitle":"Nano Banana Pro","href":"/ko/development/comfy-router/models/google/nano-banana-pro/code"}]},{"group":"HeyGen","pages":[{"title":"Comfy Router에서 Starfish 사용하기","sidebarTitle":"Starfish","href":"/ko/development/comfy-router/models/heygen/starfish/code"}]},{"group":"Higgsfield","pages":[{"title":"Higgsfield Genjutsu Motion Transfer V1.0을 Comfy Router로 사용하기","sidebarTitle":"Higgsfield Genjutsu Motion Transfer V1.0","href":"/ko/development/comfy-router/models/higgsfield/higgsfield-genjutsu-motion-transfer-v1-0/code"},{"title":"Comfy Router로 Higgsfield Kling 3.4k 사용하기","sidebarTitle":"Higgsfield Kling 3.4k","href":"/ko/development/comfy-router/models/higgsfield/higgsfield-kling-3-4k/code"},{"title":"Comfy Router로 Higgsfield Kling 3 Pro 사용하기","sidebarTitle":"Higgsfield Kling 3 Pro","href":"/ko/development/comfy-router/models/higgsfield/higgsfield-kling-3-pro/code"}]},{"group":"Ideogram","pages":[{"title":"Comfy Router로 Ideogram 4.5 사용하기","sidebarTitle":"Ideogram 4.5","href":"/ko/development/comfy-router/models/ideogram/ideogram-4-5/code"},{"title":"Comfy Router로 Ideogram V3 사용하기","sidebarTitle":"Ideogram V3","href":"/ko/development/comfy-router/models/ideogram/ideogram-v3/code"},{"title":"Comfy Router로 Ideogram 4.0 사용하기","sidebarTitle":"Ideogram 4.0","href":"/ko/development/comfy-router/models/ideogram/ideogram-v4/code"},{"title":"Comfy Router로 P Image Ideogram 사용하기","sidebarTitle":"P Image Ideogram","href":"/ko/development/comfy-router/models/ideogram/p-image-ideogram/code"}]},{"group":"Kling","pages":[{"title":"Comfy Router로 Kling 3.0 Turbo 사용하기","sidebarTitle":"Kling 3.0 Turbo","href":"/ko/development/comfy-router/models/kling/kling-3-0-turbo/code"},{"title":"Comfy Router로 Kling 4.0 사용하기","sidebarTitle":"Kling 4.0","href":"/ko/development/comfy-router/models/kling/kling-4-0/code"},{"title":"Comfy Router와 함께 Kling Image O1 사용하기","sidebarTitle":"Kling Image O1","href":"/ko/development/comfy-router/models/kling/kling-image-o1/code"},{"title":"Comfy Router로 Kling V2.5 Turbo 사용하기","sidebarTitle":"Kling V2.5 Turbo","href":"/ko/development/comfy-router/models/kling/kling-v2-5-turbo/code"},{"title":"Comfy Router로 Kling V2.6 사용하기","sidebarTitle":"Kling V2.6","href":"/ko/development/comfy-router/models/kling/kling-v2-6/code"},{"title":"Comfy Router로 Kling V3 Omni 사용하기","sidebarTitle":"Kling V3 Omni","href":"/ko/development/comfy-router/models/kling/kling-v3-omni/code"},{"title":"Comfy Router로 Kling V3 사용하기","sidebarTitle":"Kling V3","href":"/ko/development/comfy-router/models/kling/kling-v3/code"},{"title":"Comfy Router로 Kling Video O1 사용하기","sidebarTitle":"Kling Video O1","href":"/ko/development/comfy-router/models/kling/kling-video-o1/code"},{"title":"Comfy Router로 Videos Avatar Image 2video 사용하기","sidebarTitle":"Videos Avatar Image 2video","href":"/ko/development/comfy-router/models/kling/videos-avatar-image2video/code"},{"title":"Comfy Router로 Videos Lip Sync 사용하기","sidebarTitle":"Videos Lip Sync","href":"/ko/development/comfy-router/models/kling/videos-lip-sync/code"}]},{"group":"Krea","pages":[{"title":"Comfy Router로 Krea 2 Large 사용하기","sidebarTitle":"Krea 2 Large","href":"/ko/development/comfy-router/models/krea/krea-2-large/code"},{"title":"Comfy Router로 Krea 2 Medium Turbo 사용하기","sidebarTitle":"Krea 2 Medium Turbo","href":"/ko/development/comfy-router/models/krea/krea-2-medium-turbo/code"},{"title":"Comfy Router로 Krea 2 Medium 사용하기","sidebarTitle":"Krea 2 Medium","href":"/ko/development/comfy-router/models/krea/krea-2-medium/code"},{"title":"Comfy Router로 Krea 2 사용하기","sidebarTitle":"Krea 2","href":"/ko/development/comfy-router/models/krea/krea-2/code"},{"title":"Comfy Router로 Krea 3 사용하기","sidebarTitle":"Krea 3","href":"/ko/development/comfy-router/models/krea/krea-3/code"}]},{"group":"LTX","pages":[{"title":"Comfy Router로 LTX 2.5 Fast 사용하기","sidebarTitle":"LTX 2.5 Fast","href":"/ko/development/comfy-router/models/ltx/ltx-2-5-fast/code"},{"title":"Comfy Router로 LTX 2.5 Pro 사용하기","sidebarTitle":"LTX 2.5 Pro","href":"/ko/development/comfy-router/models/ltx/ltx-2-5-pro/code"}]},{"group":"Luma","pages":[{"title":"Comfy Router로 Photon 1 사용하기","sidebarTitle":"Photon 1","href":"/ko/development/comfy-router/models/luma/photon-1/code"},{"title":"Comfy Router로 Photon Flash 1 사용하기","sidebarTitle":"Photon Flash 1","href":"/ko/development/comfy-router/models/luma/photon-flash-1/code"}]},{"group":"Luma 2","pages":[{"title":"Comfy Router로 Ray 3.2 사용하기","sidebarTitle":"Ray 3.2","href":"/ko/development/comfy-router/models/luma_2/ray-3-2/code"},{"title":"Comfy Router로 Uni 1 Max 사용하기","sidebarTitle":"Uni 1 Max","href":"/ko/development/comfy-router/models/luma_2/uni-1-max/code"},{"title":"Comfy Router에서 Uni 1 사용하기","sidebarTitle":"Uni 1","href":"/ko/development/comfy-router/models/luma_2/uni-1/code"}]},{"group":"Meshy","pages":[{"title":"Comfy Router로 애니메이션 사용하기","sidebarTitle":"애니메이션","href":"/ko/development/comfy-router/models/meshy/animations/code"},{"title":"Comfy Router로 Meshy 6 사용하기","sidebarTitle":"Meshy 6","href":"/ko/development/comfy-router/models/meshy/meshy-6/code"},{"title":"Comfy Router로 Meshy 7.1 사용하기","sidebarTitle":"Meshy 7.1","href":"/ko/development/comfy-router/models/meshy/meshy-7-1/code"},{"title":"Comfy Router로 Meshy 7 사용하기","sidebarTitle":"Meshy 7","href":"/ko/development/comfy-router/models/meshy/meshy-7/code"},{"title":"Comfy Router에서 Remesh 사용하기","sidebarTitle":"Remesh","href":"/ko/development/comfy-router/models/meshy/remesh/code"},{"title":"Comfy Router로 Rigging 사용하기","sidebarTitle":"Rigging","href":"/ko/development/comfy-router/models/meshy/rigging/code"}]},{"group":"MiniMax","pages":[{"title":"Comfy Router로 MiniMax H3 사용하기","sidebarTitle":"MiniMax H3","href":"/ko/development/comfy-router/models/minimax/minimax-h3/code"}]},{"group":"Moonvalley","pages":[{"title":"Comfy Router로 이미지 기반 비디오 생성 사용하기","sidebarTitle":"이미지 기반 비디오 생성","href":"/ko/development/comfy-router/models/moonvalley/image-to-video/code"},{"title":"Comfy Router로 텍스트 기반 비디오 생성 사용하기","sidebarTitle":"텍스트 기반 비디오 생성","href":"/ko/development/comfy-router/models/moonvalley/text-to-video/code"},{"title":"Comfy Router로 Video To Video 사용하기","sidebarTitle":"비디오 기반 비디오 생성","href":"/ko/development/comfy-router/models/moonvalley/video-to-video/code"}]},{"group":"OpenAI","pages":[{"title":"Comfy Router에서 GPT 4.1 Mini 사용하기","sidebarTitle":"GPT 4.1 Mini","href":"/ko/development/comfy-router/models/openai/gpt-4-1-mini/code"},{"title":"Comfy Router로 GPT 4.1 사용하기","sidebarTitle":"GPT 4.1","href":"/ko/development/comfy-router/models/openai/gpt-4-1/code"},{"title":"Comfy Router와 함께 GPT 4o 사용하기","sidebarTitle":"GPT 4o","href":"/ko/development/comfy-router/models/openai/gpt-4o/code"},{"title":"Comfy Router로 GPT 5.5 Pro 사용하기","sidebarTitle":"GPT 5.5 Pro","href":"/ko/development/comfy-router/models/openai/gpt-5-5-pro/code"},{"title":"GPT 5.5를 Comfy Router와 함께 사용하기","sidebarTitle":"GPT 5.5","href":"/ko/development/comfy-router/models/openai/gpt-5-5/code"},{"title":"Comfy Router로 GPT 5.6 Luna 사용하기","sidebarTitle":"GPT 5.6 Luna","href":"/ko/development/comfy-router/models/openai/gpt-5-6-luna/code"},{"title":"Comfy Router와 함께 GPT 5.6 Sol 사용하기","sidebarTitle":"GPT 5.6 Sol","href":"/ko/development/comfy-router/models/openai/gpt-5-6-sol/code"},{"title":"Comfy Router에서 GPT 5.6 Terra 사용하기","sidebarTitle":"GPT 5.6 Terra","href":"/ko/development/comfy-router/models/openai/gpt-5-6-terra/code"},{"title":"Comfy Router에서 GPT 5 Mini 사용하기","sidebarTitle":"GPT 5 Mini","href":"/ko/development/comfy-router/models/openai/gpt-5-mini/code"},{"title":"Comfy Router로 GPT 5 Nano 사용하기","sidebarTitle":"GPT 5 Nano","href":"/ko/development/comfy-router/models/openai/gpt-5-nano/code"},{"title":"Comfy Router에서 GPT 5 사용하기","sidebarTitle":"GPT 5","href":"/ko/development/comfy-router/models/openai/gpt-5/code"},{"title":"Comfy Router로 GPT 6.1 Sol 사용하기","sidebarTitle":"GPT 6.1 Sol","href":"/ko/development/comfy-router/models/openai/gpt-6-1-sol/code"},{"title":"Comfy Router와 함께 GPT 6.1 Terra 사용하기","sidebarTitle":"GPT 6.1 Terra","href":"/ko/development/comfy-router/models/openai/gpt-6-1-terra/code"},{"title":"Comfy Router와 함께 GPT 6 Astra 사용하기","sidebarTitle":"GPT 6 Astra","href":"/ko/development/comfy-router/models/openai/gpt-6-astra/code"},{"title":"Comfy Router에서 GPT 6 Luna 사용하기","sidebarTitle":"GPT 6 Luna","href":"/ko/development/comfy-router/models/openai/gpt-6-luna/code"},{"title":"Comfy Router로 GPT 6 Sol 사용하기","sidebarTitle":"GPT 6 Sol","href":"/ko/development/comfy-router/models/openai/gpt-6-sol/code"},{"title":"Comfy Router로 GPT Image 1.5 사용하기","sidebarTitle":"GPT Image 1.5","href":"/ko/development/comfy-router/models/openai/gpt-image-1-5/code"},{"title":"Comfy Router에서 GPT Image 2.5 Flare 사용하기","sidebarTitle":"GPT Image 2.5 Flare","href":"/ko/development/comfy-router/models/openai/gpt-image-2-5-flare/code"},{"title":"Comfy Router로 GPT Image 2.5 Sunburst 사용하기","sidebarTitle":"GPT Image 2.5 Sunburst","href":"/ko/development/comfy-router/models/openai/gpt-image-2-5-sunburst/code"},{"title":"Comfy Router에서 GPT Image 2.6 Flare 사용하기","sidebarTitle":"GPT Image 2.6 Flare","href":"/ko/development/comfy-router/models/openai/gpt-image-2-6-flare/code"},{"title":"Comfy Router로 GPT Image 2.6 Sunburst 사용하기","sidebarTitle":"GPT Image 2.6 Sunburst","href":"/ko/development/comfy-router/models/openai/gpt-image-2-6-sunburst/code"},{"title":"Comfy Router에서 GPT Image 2 사용하기","sidebarTitle":"GPT Image 2","href":"/ko/development/comfy-router/models/openai/gpt-image-2/code"},{"title":"Comfy Router와 함께 o3 사용하기","sidebarTitle":"o3","href":"/ko/development/comfy-router/models/openai/o3/code"}]},{"group":"Pika","pages":[{"title":"Comfy Router로 Pika 2.5 이미지 기반 비디오 생성 사용하기","sidebarTitle":"Pika 2.5 이미지 기반 비디오 생성","href":"/ko/development/comfy-router/models/pika/pika-2-5-image-to-video/code"},{"title":"Comfy Router에서 Pika Soundtrack 사용하기","sidebarTitle":"Pika Soundtrack","href":"/ko/development/comfy-router/models/pika/pika-soundtrack/code"},{"title":"Comfy Router로 Pika Sfx 사용하기","sidebarTitle":"Pika Sfx","href":"/ko/development/comfy-router/models/pika/pika-sfx/code"},{"title":"Comfy Router에서 Pika Music 사용하기","sidebarTitle":"Pika Music","href":"/ko/development/comfy-router/models/pika/pika-music/code"},{"title":"Comfy Router로 Pika 2.5 텍스트 기반 비디오 생성 사용하기","sidebarTitle":"Pika 2.5 텍스트 기반 비디오 생성","href":"/ko/development/comfy-router/models/pika/pika-2-5-text-to-video/code"},{"title":"Comfy Router로 Pika H3 Flex 이미지 기반 비디오 생성 사용하기","sidebarTitle":"Pika H3 Flex 이미지 기반 비디오 생성","href":"/ko/development/comfy-router/models/pika/pika-h3-flex-image-to-video/code"},{"title":"Comfy Router로 Pika H3 Flex Reference To Video 사용하기","sidebarTitle":"Pika H3 Flex Reference To Video","href":"/ko/development/comfy-router/models/pika/pika-h3-flex-reference-to-video/code"},{"title":"Comfy Router로 Pika H3 Flex Text To Video 사용하기","sidebarTitle":"Pika H3 Flex Text To Video","href":"/ko/development/comfy-router/models/pika/pika-h3-flex-text-to-video/code"}]},{"group":"Pruna","pages":[{"title":"Comfy Router로 P Video 2 사용하기","sidebarTitle":"P Video 2","href":"/ko/development/comfy-router/models/pruna/p-video-2/code"}]},{"group":"Qwen","pages":[{"title":"Comfy Router로 Qwen Image 3.0 Pro 사용하기","sidebarTitle":"Qwen Image 3.0 Pro","href":"/ko/development/comfy-router/models/qwen/qwen-image-3-0-pro/code"},{"title":"Comfy Router로 Qwen Image 3.0 사용하기","sidebarTitle":"Qwen Image 3.0","href":"/ko/development/comfy-router/models/qwen/qwen-image-3-0/code"}]},{"group":"Recraft","pages":[{"title":"Comfy Router에서 Recraft V2 사용하기","sidebarTitle":"Recraft V2","href":"/ko/development/comfy-router/models/recraft/recraftv2/code"},{"title":"Comfy Router로 Recraft V3 사용하기","sidebarTitle":"Recraft V3","href":"/ko/development/comfy-router/models/recraft/recraftv3/code"},{"title":"Comfy Router로 Recraft V4.1 Pro Vector 사용하기","sidebarTitle":"Recraft V4.1 Pro Vector","href":"/ko/development/comfy-router/models/recraft/recraftv4-1-pro-vector/code"},{"title":"Comfy Router로 Recraft V4.1 Pro 사용하기","sidebarTitle":"Recraft V4.1 Pro","href":"/ko/development/comfy-router/models/recraft/recraftv4-1-pro/code"},{"title":"Comfy Router로 Recraft V4.1 Utility Pro Vector 사용하기","sidebarTitle":"Recraft V4.1 Utility Pro Vector","href":"/ko/development/comfy-router/models/recraft/recraftv4-1-utility-pro-vector/code"},{"title":"Comfy Router에서 Recraft V4.1 Utility Pro 사용하기","sidebarTitle":"Recraft V4.1 Utility Pro","href":"/ko/development/comfy-router/models/recraft/recraftv4-1-utility-pro/code"},{"title":"Comfy Router로 Recraft V4.1 Utility Vector 사용하기","sidebarTitle":"Recraft V4.1 Utility Vector","href":"/ko/development/comfy-router/models/recraft/recraftv4-1-utility-vector/code"},{"title":"Comfy Router로 Recraft V4.1 Utility 사용하기","sidebarTitle":"Recraft V4.1 Utility","href":"/ko/development/comfy-router/models/recraft/recraftv4-1-utility/code"},{"title":"Comfy Router로 Recraft V4.1 Vector 사용하기","sidebarTitle":"Recraft V4.1 Vector","href":"/ko/development/comfy-router/models/recraft/recraftv4-1-vector/code"},{"title":"Comfy Router로 Recraft V4.1 사용하기","sidebarTitle":"Recraft V4.1","href":"/ko/development/comfy-router/models/recraft/recraftv4-1/code"},{"title":"Comfy Router로 Recraft V4 Pro 사용하기","sidebarTitle":"Recraft V4 Pro","href":"/ko/development/comfy-router/models/recraft/recraftv4-pro/code"},{"title":"Comfy Router로 Recraft V4 Styles Pro Vector 사용하기","sidebarTitle":"Recraft V4 Styles Pro Vector","href":"/ko/development/comfy-router/models/recraft/recraftv4-styles-pro-vector/code"},{"title":"Comfy Router로 Recraft V4 Styles Pro 사용하기","sidebarTitle":"Recraft V4 Styles Pro","href":"/ko/development/comfy-router/models/recraft/recraftv4-styles-pro/code"},{"title":"Comfy Router로 Recraft V4 Styles Vector 사용하기","sidebarTitle":"Recraft V4 Styles Vector","href":"/ko/development/comfy-router/models/recraft/recraftv4-styles-vector/code"},{"title":"Comfy Router로 Recraft V4 Styles 사용하기","sidebarTitle":"Recraft V4 Styles","href":"/ko/development/comfy-router/models/recraft/recraftv4-styles/code"},{"title":"Comfy Router로 Recraft V4 사용하기","sidebarTitle":"Recraft V4","href":"/ko/development/comfy-router/models/recraft/recraftv4/code"}]},{"group":"Runway","pages":[{"title":"Comfy Router로 Aleph 2 사용하기","sidebarTitle":"Aleph 2","href":"/ko/development/comfy-router/models/runway/aleph2/code"},{"title":"Comfy Router로 Gen 4 Image 사용하기","sidebarTitle":"Gen 4 Image","href":"/ko/development/comfy-router/models/runway/gen4-image/code"},{"title":"Comfy Router로 Gen 4 Turbo 사용하기","sidebarTitle":"Gen 4 Turbo","href":"/ko/development/comfy-router/models/runway/gen4-turbo/code"}]},{"group":"Stability","pages":[{"title":"Comfy Router로 Control Sketch 사용하기","sidebarTitle":"Control Sketch","href":"/ko/development/comfy-router/models/stability/control-sketch/code"},{"title":"Comfy Router로 Control Structure 사용하기","sidebarTitle":"Control Structure","href":"/ko/development/comfy-router/models/stability/control-structure/code"},{"title":"Comfy Router로 Control Style Transfer 사용하기","sidebarTitle":"Control Style Transfer","href":"/ko/development/comfy-router/models/stability/control-style-transfer/code"},{"title":"Comfy Router로 Control Style 사용하기","sidebarTitle":"Control Style","href":"/ko/development/comfy-router/models/stability/control-style/code"},{"title":"Comfy Router로 Edit Erase 사용","sidebarTitle":"Edit Erase","href":"/ko/development/comfy-router/models/stability/edit-erase/code"},{"title":"Comfy Router로 Edit Inpaint 사용하기","sidebarTitle":"Edit Inpaint","href":"/ko/development/comfy-router/models/stability/edit-inpaint/code"},{"title":"Comfy Router로 Edit Outpaint 사용하기","sidebarTitle":"Edit Outpaint","href":"/ko/development/comfy-router/models/stability/edit-outpaint/code"},{"title":"Comfy Router로 Edit Remove Background 사용하기","sidebarTitle":"Edit Remove Background","href":"/ko/development/comfy-router/models/stability/edit-remove-background/code"},{"title":"Comfy Router로 Edit Replace Background And Relight 사용하기","sidebarTitle":"Edit Replace Background And Relight","href":"/ko/development/comfy-router/models/stability/edit-replace-background-and-relight/code"},{"title":"Comfy Router로 Edit Search And Recolor 사용하기","sidebarTitle":"Edit Search And Recolor","href":"/ko/development/comfy-router/models/stability/edit-search-and-recolor/code"},{"title":"Comfy Router로 Edit Search And Replace 사용하기","sidebarTitle":"Edit Search And Replace","href":"/ko/development/comfy-router/models/stability/edit-search-and-replace/code"},{"title":"Comfy Router로 Generate Core 사용하기","sidebarTitle":"Generate Core","href":"/ko/development/comfy-router/models/stability/generate-core/code"},{"title":"Comfy Router로 Generate Ultra 사용하기","sidebarTitle":"Generate Ultra","href":"/ko/development/comfy-router/models/stability/generate-ultra/code"},{"title":"Comfy Router에서 Sd3.5 Flash 사용하기","sidebarTitle":"Sd3.5 Flash","href":"/ko/development/comfy-router/models/stability/sd3-5-flash/code"},{"title":"Comfy Router에서 Sd3.5 Large Turbo 사용하기","sidebarTitle":"Sd3.5 Large Turbo","href":"/ko/development/comfy-router/models/stability/sd3-5-large-turbo/code"},{"title":"Comfy Router로 Sd3.5 Large 사용하기","sidebarTitle":"Sd3.5 Large","href":"/ko/development/comfy-router/models/stability/sd3-5-large/code"},{"title":"Comfy Router로 Sd3.5 Medium 사용하기","sidebarTitle":"Sd3.5 Medium","href":"/ko/development/comfy-router/models/stability/sd3-5-medium/code"},{"title":"Sdxl 1.0 이미지 기반 이미지 생성을 Comfy Router와 함께 사용하기","sidebarTitle":"Sdxl 1.0 이미지 기반 이미지 생성","href":"/ko/development/comfy-router/models/stability/sdxl-1-0-image-to-image/code"},{"title":"Comfy Router로 Sdxl 1.0 Masking 사용하기","sidebarTitle":"Sdxl 1.0 Masking","href":"/ko/development/comfy-router/models/stability/sdxl-1-0-masking/code"},{"title":"Comfy Router로 Sdxl 1.0 Text To Image 사용하기","sidebarTitle":"Sdxl 1.0 Text To Image","href":"/ko/development/comfy-router/models/stability/sdxl-1-0-text-to-image/code"},{"title":"Comfy Router로 Stable Fast 3D 사용하기","sidebarTitle":"Stable Fast 3D","href":"/ko/development/comfy-router/models/stability/stable-fast-3d/code"},{"title":"Comfy Router로 Stable Point Aware 3D 사용하기","sidebarTitle":"Stable Point Aware 3D","href":"/ko/development/comfy-router/models/stability/stable-point-aware-3d/code"},{"title":"Comfy Router로 Upscale Conservative 사용하기","sidebarTitle":"Upscale Conservative","href":"/ko/development/comfy-router/models/stability/upscale-conservative/code"},{"title":"Comfy Router에서 Upscale Creative 사용하기","sidebarTitle":"Upscale Creative","href":"/ko/development/comfy-router/models/stability/upscale-creative/code"},{"title":"Comfy Router로 Upscale Fast 사용하기","sidebarTitle":"Upscale Fast","href":"/ko/development/comfy-router/models/stability/upscale-fast/code"}]},{"group":"Synclabs","pages":[{"title":"Comfy Router로 Sync 3 사용하기","sidebarTitle":"Sync 3","href":"/ko/development/comfy-router/models/synclabs/sync-3/code"}]},{"group":"Tencent","pages":[{"title":"Comfy Router로 Hunyuan 3D Part 사용하기","sidebarTitle":"Hunyuan 3D Part","href":"/ko/development/comfy-router/models/tencent/hunyuan-3d-part/code"},{"title":"Comfy Router로 Hunyuan 3D Smart Topology 사용하기","sidebarTitle":"Hunyuan 3D Smart Topology","href":"/ko/development/comfy-router/models/tencent/hunyuan-3d-smart-topology/code"},{"title":"Comfy Router로 Hunyuan 3D Texture Edit 사용하기","sidebarTitle":"Hunyuan 3D Texture Edit","href":"/ko/development/comfy-router/models/tencent/hunyuan-3d-texture-edit/code"},{"title":"Comfy Router로 Hunyuan 3D Uv 사용하기","sidebarTitle":"Hunyuan 3D Uv","href":"/ko/development/comfy-router/models/tencent/hunyuan-3d-uv/code"}]},{"group":"Veed","pages":[{"title":"Comfy Router로 Clean Audio Video 사용하기","sidebarTitle":"Clean Audio Video","href":"/ko/development/comfy-router/models/veed/clean-audio-video/code"},{"title":"Comfy Router로 Clean Audio 사용하기","sidebarTitle":"Clean Audio","href":"/ko/development/comfy-router/models/veed/clean-audio/code"},{"title":"Comfy Router에서 Fabric 1.0 사용하기","sidebarTitle":"Fabric 1.0","href":"/ko/development/comfy-router/models/veed/fabric-1-0/code"},{"title":"Comfy Router로 Lipsync 2.0 사용하기","sidebarTitle":"Lipsync 2.0","href":"/ko/development/comfy-router/models/veed/lipsync-2-0/code"},{"title":"Comfy Router로 Video Background Removal Fast 사용하기","sidebarTitle":"Video Background Removal Fast","href":"/ko/development/comfy-router/models/veed/video-background-removal-fast/code"},{"title":"Comfy Router로 Video Background Removal Green Screen 사용하기","sidebarTitle":"Video Background Removal Green Screen","href":"/ko/development/comfy-router/models/veed/video-background-removal-green-screen/code"},{"title":"Comfy Router로 Video Background Removal 사용하기","sidebarTitle":"Video Background Removal","href":"/ko/development/comfy-router/models/veed/video-background-removal/code"}]},{"group":"Veo","pages":[{"title":"Comfy Router로 Veo 3.1 Fast Generate 001 사용하기","sidebarTitle":"Veo 3.1 Fast Generate 001","href":"/ko/development/comfy-router/models/veo/veo-3-1-fast-generate-001/code"},{"title":"Comfy Router로 Veo 3.1 Generate 001 사용하기","sidebarTitle":"Veo 3.1 Generate 001","href":"/ko/development/comfy-router/models/veo/veo-3-1-generate-001/code"},{"title":"Comfy Router로 Veo 3.1 Lite Generate 001 사용하기","sidebarTitle":"Veo 3.1 Lite Generate 001","href":"/ko/development/comfy-router/models/veo/veo-3-1-lite-generate-001/code"}]},{"group":"Wan","pages":[{"title":"Comfy Router로 HappyHorse 1.0 I2V 사용하기","sidebarTitle":"HappyHorse 1.0 I2V","href":"/ko/development/comfy-router/models/wan/happyhorse-1-0-i2v/code"},{"title":"Comfy Router로 HappyHorse 1.0 R2V 사용하기","sidebarTitle":"HappyHorse 1.0 R2V","href":"/ko/development/comfy-router/models/wan/happyhorse-1-0-r2v/code"},{"title":"Comfy Router로 HappyHorse 1.0 T2V 사용하기","sidebarTitle":"HappyHorse 1.0 T2V","href":"/ko/development/comfy-router/models/wan/happyhorse-1-0-t2v/code"},{"title":"Comfy Router로 HappyHorse 1.0 Video Edit 사용하기","sidebarTitle":"HappyHorse 1.0 Video Edit","href":"/ko/development/comfy-router/models/wan/happyhorse-1-0-video-edit/code"},{"title":"Comfy Router로 HappyHorse 1.1 I2V 사용하기","sidebarTitle":"HappyHorse 1.1 I2V","href":"/ko/development/comfy-router/models/wan/happyhorse-1-1-i2v/code"},{"title":"Comfy Router로 HappyHorse 1.1 R2V 사용하기","sidebarTitle":"HappyHorse 1.1 R2V","href":"/ko/development/comfy-router/models/wan/happyhorse-1-1-r2v/code"},{"title":"Comfy Router로 HappyHorse 1.1 T2V 사용하기","sidebarTitle":"HappyHorse 1.1 T2V","href":"/ko/development/comfy-router/models/wan/happyhorse-1-1-t2v/code"},{"title":"Wan 2.5 I2I Preview를 Comfy Router와 함께 사용하기","sidebarTitle":"Wan 2.5 I2I Preview","href":"/ko/development/comfy-router/models/wan/wan2-5-i2i-preview/code"},{"title":"Comfy Router로 Wan 2.5 I2V Preview 사용하기","sidebarTitle":"Wan 2.5 I2V Preview","href":"/ko/development/comfy-router/models/wan/wan2-5-i2v-preview/code"},{"title":"Comfy Router로 Wan 2.5 T2I Preview 사용하기","sidebarTitle":"Wan 2.5 T2I Preview","href":"/ko/development/comfy-router/models/wan/wan2-5-t2i-preview/code"},{"title":"Comfy Router로 Wan 2.5 T2V Preview 사용하기","sidebarTitle":"Wan 2.5 T2V Preview","href":"/ko/development/comfy-router/models/wan/wan2-5-t2v-preview/code"},{"title":"Comfy Router로 Wan 2.6 I2V 사용하기","sidebarTitle":"Wan 2.6 I2V","href":"/ko/development/comfy-router/models/wan/wan2-6-i2v/code"},{"title":"Comfy Router로 Wan 2.6 R2V 사용하기","sidebarTitle":"Wan 2.6 R2V","href":"/ko/development/comfy-router/models/wan/wan2-6-r2v/code"},{"title":"Comfy Router로 Wan 2.6 T2V 사용하기","sidebarTitle":"Wan 2.6 T2V","href":"/ko/development/comfy-router/models/wan/wan2-6-t2v/code"},{"title":"Comfy Router로 Wan 2.7 I2V 사용하기","sidebarTitle":"Wan 2.7 I2V","href":"/ko/development/comfy-router/models/wan/wan2-7-i2v/code"},{"title":"Comfy Router로 Wan 2.7 R2V 사용하기","sidebarTitle":"Wan 2.7 R2V","href":"/ko/development/comfy-router/models/wan/wan2-7-r2v/code"},{"title":"Comfy Router로 Wan 2.7 T2V 사용하기","sidebarTitle":"Wan 2.7 T2V","href":"/ko/development/comfy-router/models/wan/wan2-7-t2v/code"},{"title":"Comfy Router로 Wan 2.7 Video Edit 사용하기","sidebarTitle":"Wan 2.7 Video Edit","href":"/ko/development/comfy-router/models/wan/wan2-7-videoedit/code"},{"title":"Comfy Router로 Wan 3.0 Video Prime 사용하기","sidebarTitle":"Wan 3.0 Video Prime","href":"/ko/development/comfy-router/models/wan/wan3-0-video-prime/code"},{"title":"Comfy Router로 Wan 3.0 Video 사용하기","sidebarTitle":"Wan 3.0 Video","href":"/ko/development/comfy-router/models/wan/wan3-0-video/code"}]},{"group":"WaveSpeed","pages":[{"title":"Comfy Router로 Flashvsr 사용하기","sidebarTitle":"Flashvsr","href":"/ko/development/comfy-router/models/wavespeed/flashvsr/code"},{"title":"Comfy Router로 Seedvr 2 사용하기","sidebarTitle":"Seedvr 2","href":"/ko/development/comfy-router/models/wavespeed/seedvr2/code"},{"title":"Comfy Router로 Ultimate Image Upscaler 사용하기","sidebarTitle":"Ultimate Image Upscaler","href":"/ko/development/comfy-router/models/wavespeed/ultimate-image-upscaler/code"}]},{"group":"xAI","pages":[{"title":"Comfy Router에서 Grok Imagine Image 2.0 사용하기","sidebarTitle":"Grok Imagine Image 2.0","href":"/ko/development/comfy-router/models/xai/grok-imagine-image-2-0/code"},{"title":"Comfy Router로 Grok Imagine Image Pro 사용하기","sidebarTitle":"Grok Imagine Image Pro","href":"/ko/development/comfy-router/models/xai/grok-imagine-image-pro/code"},{"title":"Comfy Router로 Grok Imagine Image Quality 사용하기","sidebarTitle":"Grok Imagine Image Quality","href":"/ko/development/comfy-router/models/xai/grok-imagine-image-quality/code"},{"title":"Comfy Router로 Grok Imagine Image 사용하기","sidebarTitle":"Grok Imagine Image","href":"/ko/development/comfy-router/models/xai/grok-imagine-image/code"},{"title":"Comfy Router로 Grok Imagine Video 1.5 Lite 사용하기","sidebarTitle":"Grok Imagine Video 1.5 Lite","href":"/ko/development/comfy-router/models/xai/grok-imagine-video-1-5-lite/code"},{"title":"Comfy Router로 Grok Imagine Video 1.5 Preview 사용하기","sidebarTitle":"Grok Imagine Video 1.5 Preview","href":"/ko/development/comfy-router/models/xai/grok-imagine-video-1-5-preview/code"},{"title":"Comfy Router로 Grok Imagine Video 1.5 사용하기","sidebarTitle":"Grok Imagine Video 1.5","href":"/ko/development/comfy-router/models/xai/grok-imagine-video-1-5/code"},{"title":"Comfy Router로 Grok Imagine Video 사용하기","sidebarTitle":"Grok Imagine Video","href":"/ko/development/comfy-router/models/xai/grok-imagine-video/code"}]},{"group":"Openrouter","pages":[{"title":"Comfy Router로 Chat Completions 사용하기","sidebarTitle":"Chat Completions","href":"/ko/development/comfy-router/models/openrouter/chat-completions/code"}]}]}]},{"group":"Comfy CLI","pages":[{"title":"Comfy CLI 시작하기","sidebarTitle":"시작하기","href":"/ko/comfy-cli/getting-started"},{"title":"Comfy CLI 명령 레퍼런스","sidebarTitle":"명령어 레퍼런스","href":"/ko/comfy-cli/reference"},{"title":"Comfy CLI 문제 해결: 설치 및 환경 수정","sidebarTitle":"문제 해결","href":"/ko/comfy-cli/troubleshooting"}]},{"group":"스펙","pages":[{"group":"Workflow JSON","pages":[{"title":"워크플로 JSON","href":"/ko/specs/workflow_json"},{"title":"워크플로우 JSON 0.4","href":"/ko/specs/workflow_json_0.4"}]},{"group":"노드 정의","pages":[{"title":"노드 정의 JSON","href":"/ko/specs/nodedef_json"},{"title":"노드 정의 JSON 1.0","href":"/ko/specs/nodedef_json_1_0"}]}]},{"group":"Demo Apps","pages":[{"title":"데모 앱","mode":"wide","href":"/ko/development/samples/overview"}]}]},{"tab":"커스텀 노드","pages":[{"title":"커스텀 노드","href":"/ko/custom-nodes/intro"}]},{"tab":"지원","pages":[{"title":"지원","href":"/ko/support/contact-support"}]},{"tab":"Cloud API 참조","pages":[{"title":"Cloud API 참조","href":"/ko/api-reference/cloud/workflow/get-information-about-current-prompt-executions"}]}]},{"language":"es","pages":[{"title":"es","href":"/es/api-reference/router/comfy-router/read-one-partner-models-catalog-entry-by-canonical-model-id"}]}]},"basePath":"","title":"Read one partner model's catalog entry by canonical model ID. - ComfyUI","buildId":"dpl_42LwxxU1kGN114H4XzwGYXa9ZDah","deploymentId":"dpl_42LwxxU1kGN114H4XzwGYXa9ZDah","dynamics":["c2aa737661","2b790eda92","b0f84f53ff","a9bb46feb3"],"chunks":["OpenApiReferenceProvider-C-hEh3I2.js","utils-CnF4QiUD.js","cloneDeep-izs3Hzxb.js","_Uint8Array-BVIqJ90l.js","isObjectLike-C8vmzPEN.js","isArray-Dcu1dQ5t.js","utils-C7PVNbel.js","toString-BX-iyh8G.js","isSymbol-CSH9U2Gm.js","addUniqueKeysToSchema-8ytevL2A.js","snippetPresets-BT1alx3v.js","style-to-object-BY3JEAdk.js","v4-DIgz8zy6.js","conditional-requirements-CFM0id0Q.js","ApiExamples-BLXC0i_W.js","isEqual-BfaiBbcl.js","usePlaygroundInputsStore-CyLIGI9_.js","shallow-DC0lGVIW.js","getApiPlaygroundDisplay-CgDQ85tN.js","CodeSnippet-6-I-Gpv9.js","CodeSnippets-BAk1kDdu.js","Page-C945cI-W.js","getPastedJson-B276RuWN.js","icon-BqP8etTm.js","MethodPill-DM6sbxG1.js","DuplicateIcon-PyJglOaE.js","createIcon-CMeOMAc_.js","DynamicMarkdown-BoyYAA8K.js","SectionHeading-DAYv3gvZ.js","axios-vUo_bRtp.js","Markdown-BhTTmazV.js","clsx-CR-RHrVC.js","lib-DuNMoZ05.js","lib-B8HbPgcC.js","html-void-elements-mCSPHezU.js","dist-CBUH0-zX.js","katex-YMM-FMeD.js","marked.esm-CZWythHk.js","AssistantPageLink-BmARFYNC.js"]}