{"openapi":"3.1.0","info":{"title":"Neurometric API Gateway","version":"0.1.0"},"paths":{"/internal/metrics":{"get":{"summary":"Metrics","description":"Validation cache / breaker / usage-queue counters.\n\nInternal-only (blocked on the public port by restrict_internal_to_internal_port)\nso operational internals are never exposed publicly. Never 500s: every field is\nguarded for a None/partial state (TTL=0, DB-less, or test state).","operationId":"metrics_internal_metrics_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/internal/models":{"post":{"summary":"Publish Model","description":"Publish a dynamic SLM model into the registry (create-only).\n\nReturns 409 if a model with the same name already exists in either the\nstatic SLM_REGISTRY or the runtime dynamic_registry.\n\nslm_model_name must NOT include the 'neurometric/' prefix — it is stored\nunprefixed and reached by callers as 'neurometric/<name>'.","operationId":"publish_model_internal_models_post","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublishModelRequest"}}}},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"get":{"summary":"List Models","description":"Operator index of every model callable through this gateway.\n\nLists neurometric SLMs (static SLM_REGISTRY + runtime dynamic_registry, dynamic\nwinning on name collision) followed by the raw LiteLLM base models this\nenvironment serves. Base models come from the cached discovery set\n(available_backends), so this is a pure in-memory read — no live LiteLLM call,\nno side effects, never fails closed. When discovery hasn't landed\n(available_backends is None), base models are omitted and litellm_discovery\nreports the unknown state.\n\n`?verbose=true` adds system_prompt + extra_params to each SLM entry.","operationId":"list_models_internal_models_get","parameters":[{"name":"verbose","in":"query","required":false,"schema":{"type":"boolean","default":false,"title":"Verbose"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/internal/models/{slm_model_name}":{"delete":{"summary":"Unpublish Model","description":"Unpublish a dynamic SLM model from the registry.\n\nCannot delete pure static models (ones only in SLM_REGISTRY with no\ndynamic override). Can remove dynamic overrides of static models.","operationId":"unpublish_model_internal_models__slm_model_name__delete","parameters":[{"name":"slm_model_name","in":"path","required":true,"schema":{"type":"string","title":"Slm Model Name"}}],"responses":{"204":{"description":"Successful Response"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/internal/failover":{"get":{"summary":"List Failover","description":"Every policy this pod is routing on, for reconciliation and debugging.\n\nReads the in-memory map, not the database, precisely so it answers \"what is\nTHIS pod doing\" — which is the question worth asking when one pod disagrees.","operationId":"list_failover_internal_failover_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}},"post":{"summary":"Put Failover","description":"Upsert a policy. Idempotent: a revision <= the stored one is a no-op.\n\nAnswers with the EFFECTIVE row either way, so studio can compare the returned\nrevision to what it sent and know whether its push landed.","operationId":"put_failover_internal_failover_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/FailoverRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/internal/failover/{org_id}/{slm_model}":{"delete":{"summary":"Remove Failover","description":"Drop a policy. `slm_model` is a :path so the neurometric/ prefix survives.","operationId":"remove_failover_internal_failover__org_id___slm_model__delete","parameters":[{"name":"org_id","in":"path","required":true,"schema":{"type":"string","title":"Org Id"}},{"name":"slm_model","in":"path","required":true,"schema":{"type":"string","title":"Slm Model"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/slms":{"get":{"summary":"List Slms Route","operationId":"list_slms_route_v1_slms_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}},"post":{"summary":"Create Slm","operationId":"create_slm_v1_slms_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSLMRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/slms/{slm_id}":{"get":{"summary":"Get Slm Route","operationId":"get_slm_route_v1_slms__slm_id__get","parameters":[{"name":"slm_id","in":"path","required":true,"schema":{"type":"string","title":"Slm Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"delete":{"summary":"Delete Slm Route","operationId":"delete_slm_route_v1_slms__slm_id__delete","parameters":[{"name":"slm_id","in":"path","required":true,"schema":{"type":"string","title":"Slm Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/slms/{slm_id}/documents":{"post":{"summary":"Add Documents Route","operationId":"add_documents_route_v1_slms__slm_id__documents_post","parameters":[{"name":"slm_id","in":"path","required":true,"schema":{"type":"string","title":"Slm Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/chat/completions":{"post":{"summary":"Chat Completions","description":"OpenAI-compatible chat completions endpoint - passthrough to LiteLLM.","operationId":"chat_completions_v1_chat_completions_post","requestBody":{"content":{"application/json":{"schema":{"additionalProperties":true,"type":"object","title":"Payload"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/audio/transcriptions":{"post":{"summary":"Audio Transcriptions","description":"OpenAI-compatible audio transcription endpoint - passthrough to LiteLLM.","operationId":"audio_transcriptions_v1_audio_transcriptions_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/v1/models":{"get":{"summary":"Models","description":"List available models from LiteLLM.","operationId":"models_v1_models_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/models":{"get":{"summary":"Models","description":"List available models from LiteLLM.","operationId":"models_models_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/health":{"get":{"summary":"Health","description":"Health check endpoint.","operationId":"health_health_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/{org_id}/{provider_path}":{"post":{"summary":"Watch Passthrough","description":"Forward a customer's request to their provider and trace it for their org.","operationId":"watch_passthrough__org_id___provider_path__post","parameters":[{"name":"org_id","in":"path","required":true,"schema":{"type":"string","title":"Org Id"}},{"name":"provider_path","in":"path","required":true,"schema":{"type":"string","title":"Provider Path"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}}},"components":{"schemas":{"CreateSLMRequest":{"properties":{"name":{"type":"string","title":"Name"},"instructions":{"type":"string","title":"Instructions","default":""},"manifest":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Manifest"},"vertical":{"type":"string","title":"Vertical","default":"customer-support"},"documents":{"items":{"additionalProperties":true,"type":"object"},"type":"array","title":"Documents","default":[]},"chunks":{"items":{"additionalProperties":true,"type":"object"},"type":"array","title":"Chunks","default":[]}},"type":"object","required":["name"],"title":"CreateSLMRequest"},"FailoverRequest":{"properties":{"org_id":{"type":"string","title":"Org Id"},"slm_model":{"type":"string","title":"Slm Model"},"fallback_model":{"type":"string","title":"Fallback Model"},"state":{"type":"string","enum":["NORMAL","FAILED_OVER"],"title":"State","default":"NORMAL"},"enabled":{"type":"boolean","title":"Enabled","default":true},"canary_pct":{"type":"integer","title":"Canary Pct","default":5},"revision":{"type":"integer","title":"Revision"}},"type":"object","required":["org_id","slm_model","fallback_model","revision"],"title":"FailoverRequest","description":"A declarative statement of the desired policy for one (org, SLM).\n\nNot a \"flip\": studio sends the whole intended state every time, carrying a\nmonotonic `revision`. That makes retries and out-of-order delivery no-ops\nrather than corrections, which matters because the push is best-effort and\nstudio does not wait for it."},"HTTPValidationError":{"properties":{"detail":{"items":{"$ref":"#/components/schemas/ValidationError"},"type":"array","title":"Detail"}},"type":"object","title":"HTTPValidationError"},"PipelineConfigRequest":{"properties":{"gate_model":{"type":"string","title":"Gate Model"},"gate_prompt":{"type":"string","title":"Gate Prompt"},"gate_max_tokens":{"type":"integer","title":"Gate Max Tokens","default":200},"reject_content":{"type":"string","title":"Reject Content","default":"SCORE: 1"}},"type":"object","required":["gate_model","gate_prompt"],"title":"PipelineConfigRequest","description":"Pipeline configuration for two-pass gate+scorer models."},"PublishModelRequest":{"properties":{"slm_model_name":{"type":"string","title":"Slm Model Name"},"system_prompt":{"type":"string","title":"System Prompt"},"litellm_model":{"type":"string","title":"Litellm Model"},"extra_params":{"additionalProperties":true,"type":"object","title":"Extra Params","default":{}},"pipeline":{"anyOf":[{"$ref":"#/components/schemas/PipelineConfigRequest"},{"type":"null"}]},"system_prompt_mode":{"type":"string","enum":["replace","prepend","passthrough"],"title":"System Prompt Mode","default":"replace"},"strip_system_prompt":{"type":"boolean","title":"Strip System Prompt","default":false}},"type":"object","required":["slm_model_name","system_prompt","litellm_model"],"title":"PublishModelRequest","description":"Request body for publishing a dynamic SLM model."},"ValidationError":{"properties":{"loc":{"items":{"anyOf":[{"type":"string"},{"type":"integer"}]},"type":"array","title":"Location"},"msg":{"type":"string","title":"Message"},"type":{"type":"string","title":"Error Type"}},"type":"object","required":["loc","msg","type"],"title":"ValidationError"}}}}