{
 "openapi": "3.1.0",
 "info": {
  "title": "SwitchGate API",
  "version": "1.0.0",
  "description": "Every model behind one OpenAI-compatible API, with governance built in. Placeholder/demo specification.",
  "contact": {
   "email": "hello@switchgate.ai",
   "url": "https://switchgate.ai/contact/"
  }
 },
 "servers": [
  {
   "url": "https://api.switchgate.ai/v1"
  }
 ],
 "security": [
  {
   "bearerAuth": []
  }
 ],
 "components": {
  "securitySchemes": {
   "bearerAuth": {
    "type": "http",
    "scheme": "bearer",
    "bearerFormat": "sg-live-… or sg-admin-…"
   }
  },
  "schemas": {
   "ChatRequest": {
    "type": "object",
    "required": [
     "model",
     "messages"
    ],
    "properties": {
     "model": {
      "type": "string",
      "examples": [
       "anthropic/claude-sonnet-4-6",
       "switchgate/auto"
      ]
     },
     "messages": {
      "type": "array",
      "items": {
       "type": "object",
       "required": [
        "role",
        "content"
       ],
       "properties": {
        "role": {
         "type": "string",
         "enum": [
          "system",
          "user",
          "assistant",
          "tool"
         ]
        },
        "content": {}
       }
      }
     },
     "stream": {
      "type": "boolean"
     },
     "temperature": {
      "type": "number"
     },
     "max_tokens": {
      "type": "integer"
     },
     "top_p": {
      "type": "number"
     },
     "stop": {},
     "frequency_penalty": {
      "type": "number"
     },
     "presence_penalty": {
      "type": "number"
     },
     "seed": {
      "type": "integer"
     },
     "tools": {
      "type": "array"
     },
     "tool_choice": {},
     "response_format": {
      "type": "object"
     },
     "user": {
      "type": "string"
     },
     "sg_cache": {
      "type": "string",
      "enum": [
       "auto",
       "semantic",
       "off"
      ]
     },
     "sg_fallbacks": {
      "type": "array",
      "items": {
       "type": "string"
      }
     },
     "sg_pii_redaction": {
      "type": "string",
      "enum": [
       "mask",
       "block"
      ]
     },
     "metadata": {
      "type": "object",
      "additionalProperties": {
       "type": "string"
      },
      "maxProperties": 8
     }
    }
   },
   "ChatResponse": {
    "type": "object",
    "properties": {
     "id": {
      "type": "string"
     },
     "object": {
      "const": "chat.completion"
     },
     "created": {
      "type": "integer"
     },
     "model": {
      "type": "string"
     },
     "provider": {
      "type": "string"
     },
     "choices": {
      "type": "array"
     },
     "usage": {
      "type": "object",
      "properties": {
       "prompt_tokens": {
        "type": "integer"
       },
       "completion_tokens": {
        "type": "integer"
       },
       "total_tokens": {
        "type": "integer"
       },
       "sg_cost_usd": {
        "type": "number"
       },
       "sg_cache": {
        "type": "string"
       }
      }
     }
    }
   },
   "Model": {
    "type": "object",
    "properties": {
     "id": {
      "type": "string"
     },
     "provider": {
      "type": "string"
     },
     "context_window": {
      "type": "integer"
     },
     "pricing": {
      "type": "object",
      "properties": {
       "input_per_m_usd": {
        "type": "number"
       },
       "output_per_m_usd": {
        "type": "number"
       }
      }
     },
     "locked_for_key": {
      "type": "boolean"
     }
    }
   },
   "ApiKey": {
    "type": "object",
    "properties": {
     "id": {
      "type": "string"
     },
     "name": {
      "type": "string"
     },
     "user_email": {
      "type": "string"
     },
     "monthly_budget_usd": {
      "type": "number"
     },
     "allowed_models": {
      "type": "array",
      "items": {
       "type": "string"
      }
     },
     "prepaid_usd": {
      "type": "number"
     },
     "balance_usd": {
      "type": "number"
     },
     "allowed_ips": {
      "type": "array",
      "items": {
       "type": "string"
      }
     },
     "allowed_countries": {
      "type": "array",
      "items": {
       "type": "string"
      }
     },
     "pii_redaction": {
      "type": "string",
      "enum": [
       "off",
       "mask",
       "block"
      ]
     },
     "sg_cache_default": {
      "type": "string",
      "enum": [
       "auto",
       "semantic",
       "off"
      ]
     },
     "expires_at": {
      "type": "string",
      "format": "date-time"
     },
     "status": {
      "type": "string"
     },
     "rate_limit_rpm": {
      "type": "integer",
      "description": "Requests/minute cap enforced at the edge"
     },
     "max_concurrency": {
      "type": "integer",
      "description": "Max simultaneous in-flight requests"
     }
    }
   },
   "Tunnel": {
    "type": "object",
    "properties": {
     "id": {
      "type": "string"
     },
     "status": {
      "type": "string"
     },
     "runtime": {
      "type": "string"
     },
     "replicas": {
      "type": "integer"
     },
     "published_models": {
      "type": "array",
      "items": {
       "type": "string"
      }
     },
     "max_concurrency": {
      "type": "integer"
     }
    }
   },
   "Error": {
    "type": "object",
    "properties": {
     "error": {
      "type": "object",
      "properties": {
       "code": {
        "type": "string"
       },
       "message": {
        "type": "string"
       }
      }
     }
    }
   }
  }
 },
 "paths": {
  "/chat/completions": {
   "post": {
    "summary": "Create a chat completion",
    "operationId": "createChatCompletion",
    "requestBody": {
     "required": true,
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/ChatRequest"
       }
      }
     }
    },
    "responses": {
     "200": {
      "description": "Completion (SSE stream when stream=true)",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/ChatResponse"
        }
       }
      }
     },
     "429": {
      "description": "rate_limited or breaker_tripped",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      }
     }
    }
   }
  },
  "/embeddings": {
   "post": {
    "summary": "Create embeddings",
    "operationId": "createEmbeddings",
    "requestBody": {
     "required": true,
     "content": {
      "application/json": {
       "schema": {
        "type": "object",
        "required": [
         "model",
         "input"
        ],
        "properties": {
         "model": {
          "type": "string"
         },
         "input": {},
         "dimensions": {
          "type": "integer"
         }
        }
       }
      }
     }
    },
    "responses": {
     "200": {
      "description": "Embedding vectors"
     }
    }
   }
  },
  "/models": {
   "get": {
    "summary": "List models callable by this key",
    "operationId": "listModels",
    "responses": {
     "200": {
      "description": "Model list",
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "properties": {
          "data": {
           "type": "array",
           "items": {
            "$ref": "#/components/schemas/Model"
           }
          }
         }
        }
       }
      }
     }
    }
   }
  },
  "/models/{id}": {
   "get": {
    "summary": "Retrieve a model",
    "operationId": "getModel",
    "parameters": [
     {
      "name": "id",
      "in": "path",
      "required": true,
      "schema": {
       "type": "string"
      },
      "description": "Catalog ID, e.g. anthropic/claude-sonnet-4-6"
     }
    ],
    "responses": {
     "200": {
      "description": "Model",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Model"
        }
       }
      }
     },
     "404": {
      "description": "model_not_found"
     }
    }
   }
  },
  "/keys": {
   "get": {
    "summary": "List API keys (admin)",
    "operationId": "listKeys",
    "parameters": [
     {
      "name": "limit",
      "in": "query",
      "required": false,
      "schema": {
       "type": "integer",
       "maximum": 200
      },
      "description": "Page size"
     },
     {
      "name": "after",
      "in": "query",
      "required": false,
      "schema": {
       "type": "string"
      },
      "description": "Cursor: last object ID"
     }
    ],
    "responses": {
     "200": {
      "description": "Keys"
     }
    }
   },
   "post": {
    "summary": "Create an API key (admin)",
    "operationId": "createKey",
    "requestBody": {
     "required": true,
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/ApiKey"
       }
      }
     }
    },
    "responses": {
     "201": {
      "description": "Created; secret shown once",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/ApiKey"
        }
       }
      }
     }
    }
   }
  },
  "/keys/{id}": {
   "get": {
    "summary": "Retrieve a key (admin)",
    "operationId": "getKey",
    "parameters": [
     {
      "name": "id",
      "in": "path",
      "required": true,
      "schema": {
       "type": "string"
      },
      "description": "Key ID"
     }
    ],
    "responses": {
     "200": {
      "description": "Key"
     }
    }
   },
   "post": {
    "summary": "Update mutable key fields (admin)",
    "operationId": "updateKey",
    "parameters": [
     {
      "name": "id",
      "in": "path",
      "required": true,
      "schema": {
       "type": "string"
      },
      "description": "Key ID"
     }
    ],
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/ApiKey"
       }
      }
     }
    },
    "responses": {
     "200": {
      "description": "Updated key"
     }
    }
   }
  },
  "/keys/{id}/revoke": {
   "post": {
    "summary": "Revoke a key instantly (admin)",
    "operationId": "revokeKey",
    "parameters": [
     {
      "name": "id",
      "in": "path",
      "required": true,
      "schema": {
       "type": "string"
      },
      "description": "Key ID"
     }
    ],
    "responses": {
     "200": {
      "description": "Revoked"
     }
    }
   }
  },
  "/tunnels": {
   "get": {
    "summary": "List Model Tunnels (enterprise, admin)",
    "operationId": "listTunnels",
    "responses": {
     "200": {
      "description": "Tunnels",
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "properties": {
          "data": {
           "type": "array",
           "items": {
            "$ref": "#/components/schemas/Tunnel"
           }
          }
         }
        }
       }
      }
     }
    }
   }
  },
  "/tunnels/{id}/rotate": {
   "post": {
    "summary": "Rotate a tunnel's mTLS identity (enterprise, admin)",
    "operationId": "rotateTunnel",
    "parameters": [
     {
      "name": "id",
      "in": "path",
      "required": true,
      "schema": {
       "type": "string"
      },
      "description": "Tunnel ID"
     }
    ],
    "responses": {
     "200": {
      "description": "Rotated"
     }
    }
   }
  },
  "/tunnels/{id}/revoke": {
   "post": {
    "summary": "Sever a tunnel immediately (enterprise, admin)",
    "operationId": "revokeTunnel",
    "parameters": [
     {
      "name": "id",
      "in": "path",
      "required": true,
      "schema": {
       "type": "string"
      },
      "description": "Tunnel ID"
     }
    ],
    "responses": {
     "200": {
      "description": "Revoked"
     }
    }
   }
  },
  "/usage": {
   "get": {
    "summary": "Query the aggregated ledger",
    "operationId": "getUsage",
    "parameters": [
     {
      "name": "from",
      "in": "query",
      "required": false,
      "schema": {
       "type": "string",
       "format": "date-time"
      },
      "description": "Window start"
     },
     {
      "name": "to",
      "in": "query",
      "required": false,
      "schema": {
       "type": "string",
       "format": "date-time"
      },
      "description": "Window end"
     },
     {
      "name": "group_by",
      "in": "query",
      "required": false,
      "schema": {
       "type": "string",
       "enum": [
        "user",
        "key",
        "model",
        "provider"
       ]
      },
      "description": "Aggregation dimension"
     },
     {
      "name": "format",
      "in": "query",
      "required": false,
      "schema": {
       "type": "string",
       "enum": [
        "json",
        "csv"
       ]
      },
      "description": "Output format"
     }
    ],
    "responses": {
     "200": {
      "description": "Aggregated usage"
     }
    }
   }
  },
  "/usage/events": {
   "get": {
    "summary": "List raw per-call traces",
    "operationId": "listUsageEvents",
    "parameters": [
     {
      "name": "limit",
      "in": "query",
      "required": false,
      "schema": {
       "type": "integer"
      },
      "description": "Page size"
     },
     {
      "name": "after",
      "in": "query",
      "required": false,
      "schema": {
       "type": "string"
      },
      "description": "Cursor"
     }
    ],
    "responses": {
     "200": {
      "description": "Trace events"
     }
    }
   }
  }
 }
}