{
  "openapi": "3.1.0",
  "info": {
    "title": "Nirvani AI API",
    "version": "1.0.0",
    "summary": "One API for leading AI models, plus the Nirvani AI business advisor.",
    "description": "The Nirvani AI API follows the standard chat-completions format, with streaming, per-key rate limits, monthly token quotas and live usage metering. Free test keys: https://ask.nirvani.ai/get-key/. Human docs: https://ask.nirvani.ai/docs/. MCP server: POST https://api.nirvani.ai/v1/mcp.",
    "contact": {
      "name": "Nirvani Company",
      "url": "https://ask.nirvani.ai/developers/",
      "email": "sammy@nirvani.ai"
    },
    "termsOfService": "https://nirvani.ai"
  },
  "servers": [
    {
      "url": "https://api.nirvani.ai/v1",
      "description": "Production"
    }
  ],
  "security": [
    {
      "bearerAuth": []
    }
  ],
  "tags": [
    {
      "name": "Chat",
      "description": "Chat completions on Nirvani tiers."
    },
    {
      "name": "Models",
      "description": "The live model registry."
    },
    {
      "name": "Usage",
      "description": "Requests, tokens and quota for the calling key."
    },
    {
      "name": "MCP",
      "description": "Model Context Protocol server (Streamable HTTP)."
    }
  ],
  "paths": {
    "/chat/completions": {
      "post": {
        "tags": [
          "Chat"
        ],
        "operationId": "createChatCompletion",
        "summary": "Create a chat completion",
        "description": "Send messages to a Nirvani tier. Set stream to true for server-sent events (data: chunks, ending with data: [DONE]).",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ChatRequest"
              },
              "example": {
                "model": "nirvani-flash",
                "messages": [
                  {
                    "role": "user",
                    "content": "Draft a follow-up text for a missed call"
                  }
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "A completion, or an event stream when stream is true.",
            "headers": {
              "x-request-id": {
                "schema": {
                  "type": "string"
                }
              },
              "x-nirvani-model": {
                "schema": {
                  "type": "string"
                }
              },
              "x-ratelimit-tier": {
                "schema": {
                  "type": "string"
                },
                "description": "Tier and requests per minute, for example test; 20/min."
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ChatCompletion"
                }
              },
              "text/event-stream": {
                "schema": {
                  "type": "string",
                  "description": "Server-sent events, each data line a ChatCompletionChunk, ending with data: [DONE]."
                }
              }
            }
          },
          "400": {
            "description": "The request is malformed or a parameter is invalid.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "The key is missing, malformed, revoked or unknown.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "The model does not exist.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Requests per minute or the monthly token quota is exceeded.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "502": {
            "description": "The model tier failed upstream. Retry.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "503": {
            "description": "The tier is not available yet or at capacity.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/models": {
      "get": {
        "tags": [
          "Models"
        ],
        "operationId": "listModels",
        "summary": "List models",
        "security": [],
        "description": "No key needed. Returns every active tier and whether it is live on this deployment.",
        "responses": {
          "200": {
            "description": "The model list.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "object": {
                      "const": "list"
                    },
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/Model"
                      }
                    }
                  },
                  "required": [
                    "object",
                    "data"
                  ]
                }
              }
            }
          }
        }
      }
    },
    "/models/{id}": {
      "get": {
        "tags": [
          "Models"
        ],
        "operationId": "getModel",
        "summary": "Get one model",
        "security": [],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "$ref": "#/components/schemas/ModelId"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The model.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Model"
                }
              }
            }
          },
          "404": {
            "description": "The model does not exist.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/usage": {
      "get": {
        "tags": [
          "Usage"
        ],
        "operationId": "getUsage",
        "summary": "Usage for the calling key",
        "responses": {
          "200": {
            "description": "Today's numbers, the last 24 hours by hour and by model, recent requests, and the monthly quota.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Usage"
                }
              }
            }
          },
          "401": {
            "description": "The key is missing, malformed, revoked or unknown.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/mcp": {
      "post": {
        "tags": [
          "MCP"
        ],
        "operationId": "mcp",
        "summary": "MCP server (Streamable HTTP)",
        "description": "JSON-RPC 2.0 over HTTP POST, stateless, JSON responses. initialize, ping and tools/list are open; tools/call needs a key. Tools: ask_business_advisor, chat_completion, list_models, get_usage.",
        "security": [
          {},
          {
            "bearerAuth": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "oneOf": [
                  {
                    "$ref": "#/components/schemas/JsonRpcRequest"
                  },
                  {
                    "type": "array",
                    "items": {
                      "$ref": "#/components/schemas/JsonRpcRequest"
                    }
                  }
                ]
              },
              "example": {
                "jsonrpc": "2.0",
                "id": 1,
                "method": "tools/call",
                "params": {
                  "name": "ask_business_advisor",
                  "arguments": {
                    "question": "Should I raise prices 10% or add a premium tier?"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "JSON-RPC response or batch.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "202": {
            "description": "Accepted: the message was a notification."
          },
          "401": {
            "description": "tools/call without a valid key. Carries WWW-Authenticate."
          }
        }
      }
    }
  },
  "components": {
    "securitySchemes": {
      "bearerAuth": {
        "type": "http",
        "scheme": "bearer",
        "bearerFormat": "nvk_test_... or nvk_live_...",
        "description": "Keys are delivered once by email and stored only as SHA-256 hashes."
      }
    },
    "schemas": {
      "Error": {
        "type": "object",
        "properties": {
          "error": {
            "type": "object",
            "properties": {
              "message": {
                "type": "string"
              },
              "type": {
                "type": "string",
                "enum": [
                  "invalid_request_error",
                  "authentication_error",
                  "rate_limit_error",
                  "quota_exceeded",
                  "capacity",
                  "service_unavailable",
                  "server_error",
                  "delivery_error"
                ]
              },
              "code": {
                "type": [
                  "string",
                  "null"
                ]
              }
            },
            "required": [
              "message",
              "type"
            ]
          }
        },
        "required": [
          "error"
        ]
      },
      "ModelId": {
        "type": "string",
        "enum": [
          "nirvani-flash",
          "nirvani-flash-lite",
          "nirvani-pro",
          "nirvani-open"
        ]
      },
      "Message": {
        "type": "object",
        "properties": {
          "role": {
            "type": "string",
            "enum": [
              "system",
              "user",
              "assistant"
            ]
          },
          "content": {
            "oneOf": [
              {
                "type": "string"
              },
              {
                "type": "array",
                "items": {
                  "type": "object",
                  "properties": {
                    "type": {
                      "const": "text"
                    },
                    "text": {
                      "type": "string"
                    }
                  },
                  "required": [
                    "type",
                    "text"
                  ]
                }
              }
            ]
          }
        },
        "required": [
          "role",
          "content"
        ]
      },
      "ChatRequest": {
        "type": "object",
        "properties": {
          "model": {
            "$ref": "#/components/schemas/ModelId"
          },
          "messages": {
            "type": "array",
            "minItems": 1,
            "items": {
              "$ref": "#/components/schemas/Message"
            }
          },
          "stream": {
            "type": "boolean",
            "default": false
          },
          "stream_options": {
            "type": "object",
            "properties": {
              "include_usage": {
                "type": "boolean"
              }
            }
          },
          "max_tokens": {
            "type": "integer",
            "minimum": 1
          },
          "temperature": {
            "type": "number",
            "minimum": 0,
            "maximum": 2
          },
          "top_p": {
            "type": "number",
            "minimum": 0,
            "maximum": 1
          },
          "stop": {
            "oneOf": [
              {
                "type": "string"
              },
              {
                "type": "array",
                "items": {
                  "type": "string"
                },
                "maxItems": 4
              }
            ]
          }
        },
        "required": [
          "model",
          "messages"
        ]
      },
      "UsageTokens": {
        "type": "object",
        "properties": {
          "prompt_tokens": {
            "type": "integer"
          },
          "completion_tokens": {
            "type": "integer"
          },
          "total_tokens": {
            "type": "integer"
          }
        }
      },
      "ChatCompletion": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          },
          "object": {
            "const": "chat.completion"
          },
          "created": {
            "type": "integer"
          },
          "model": {
            "$ref": "#/components/schemas/ModelId"
          },
          "choices": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "index": {
                  "type": "integer"
                },
                "message": {
                  "type": "object",
                  "properties": {
                    "role": {
                      "const": "assistant"
                    },
                    "content": {
                      "type": "string"
                    }
                  }
                },
                "finish_reason": {
                  "type": [
                    "string",
                    "null"
                  ],
                  "enum": [
                    "stop",
                    "length",
                    "content_filter",
                    null
                  ]
                }
              }
            }
          },
          "usage": {
            "$ref": "#/components/schemas/UsageTokens"
          }
        },
        "required": [
          "id",
          "object",
          "created",
          "model",
          "choices"
        ]
      },
      "Model": {
        "type": "object",
        "properties": {
          "id": {
            "$ref": "#/components/schemas/ModelId"
          },
          "object": {
            "const": "model"
          },
          "created": {
            "type": "integer"
          },
          "owned_by": {
            "const": "nirvani"
          },
          "name": {
            "type": "string"
          },
          "description": {
            "type": "string"
          },
          "context_window": {
            "type": "integer"
          },
          "max_output_tokens": {
            "type": "integer"
          },
          "playground": {
            "type": "boolean"
          },
          "available": {
            "type": "boolean",
            "description": "True when the tier can answer on this deployment right now."
          }
        },
        "required": [
          "id",
          "object",
          "owned_by",
          "available"
        ]
      },
      "Usage": {
        "type": "object",
        "properties": {
          "object": {
            "const": "usage"
          },
          "scope": {
            "type": "string",
            "enum": [
              "key",
              "platform"
            ]
          },
          "key": {
            "type": "object",
            "properties": {
              "prefix": {
                "type": "string"
              },
              "type": {
                "type": "string"
              },
              "tier": {
                "type": "string"
              },
              "requests_per_minute": {
                "type": "integer"
              },
              "monthly_token_quota": {
                "type": "integer"
              },
              "tokens_used_this_month": {
                "type": "integer"
              }
            }
          },
          "today": {
            "type": "object"
          },
          "hourly_24h": {
            "type": "array",
            "items": {
              "type": "object"
            }
          },
          "by_model_24h": {
            "type": "array",
            "items": {
              "type": "object"
            }
          },
          "recent": {
            "type": "array",
            "items": {
              "type": "object"
            }
          }
        }
      },
      "JsonRpcRequest": {
        "type": "object",
        "properties": {
          "jsonrpc": {
            "const": "2.0"
          },
          "id": {
            "type": [
              "integer",
              "string"
            ]
          },
          "method": {
            "type": "string",
            "enum": [
              "initialize",
              "ping",
              "tools/list",
              "tools/call",
              "notifications/initialized"
            ]
          },
          "params": {
            "type": "object"
          }
        },
        "required": [
          "jsonrpc",
          "method"
        ]
      }
    }
  }
}
