# Vichar — Full Documentation > Vichar is an open-source, OpenAI-compatible API gateway for routing, managing, and analyzing requests across LLM providers. Use one API key, track usage and cost, configure caching and guardrails, and self-host or use the managed cloud. Current models and pricing: https://app.vichar.io/models API base URL: https://api.vichar.io/v1 · Docs: https://docs.vichar.io · Site: https://app.vichar.io This file concatenates the full text of every documentation page below. # Introduction to Vichar URL: https://docs.vichar.io/ Vichar is an open-source API gateway that sits between your applications and LLM providers like OpenAI, Anthropic, Google AI Studio, and more. It provides a unified, OpenAI-compatible API interface with built-in cost tracking, caching, and intelligent routing. ## Products [#products] These docs cover four products. Pick one from the menu at the top of the sidebar, or start here: ## How it works [#how-it-works] Point your existing SDK at `https://api.vichar.io/v1` (or your self-hosted instance) and authenticate with an Vichar API key — no code rewrites. The gateway routes each request to the right provider, tracks tokens and cost per model, provider, project, and API key, and fails over to a healthy provider when one errors. Pay per-token with prepaid credits at provider list rates. ## Why use a gateway? [#why-use-a-gateway] * **One integration** — switch models or providers by changing a model string, not your code. * **Cost visibility** — usage analytics and cost breakdowns across every provider in one dashboard. * **Reliability** — automatic provider failover when a provider fails, plus opt-in response caching per project. * **No lock-in** — open source (AGPLv3), self-hostable, and OpenAI-compatible end to end. ## Take the tour [#take-the-tour] ## Features [#features] All features are documented under https://docs.vichar.io/features; each feature page is included in full in this file. ## AI Tooling [#ai-tooling] Vichar is built to work seamlessly with AI agents and development tools. AI tooling: https://docs.vichar.io/llms.txt (docs index for LLMs), https://docs.vichar.io/llms-full.txt (this file), and https://docs.vichar.io/developers/mcp (MCP server). ## Next Steps [#next-steps] * [**Quickstart**](https://docs.vichar.io/quick-start) — Get up and running in minutes * [**Overview**](https://docs.vichar.io/overview) — Learn more about what Vichar offers * [**Self-Host**](https://docs.vichar.io/self-host) — Deploy on your own infrastructure # Overview URL: https://docs.vichar.io/overview Vichar is an open-source API gateway for Large Language Models (LLMs). It acts as a middleware between your applications and various LLM providers, allowing you to: * Route requests to multiple LLM providers (OpenAI, Anthropic, Google AI Studio, and others) * Manage API keys for different providers in one place * Track token usage and costs across all your LLM interactions * Analyze performance metrics to optimize your LLM usage ## Analyzing Your LLM Requests [#analyzing-your-llm-requests] Vichar provides detailed insights into your LLM usage: * **Usage Metrics**: Track the number of requests, tokens used, and response times * **Cost Analysis**: Monitor spending across different models and providers * **Performance Tracking**: Identify patterns and optimize your prompts based on actual usage data * **Breakdown by Model**: Compare different models' performance and cost-effectiveness All this data is automatically collected and presented in an intuitive dashboard, helping you make informed decisions about your LLM strategy. ## Getting Started [#getting-started] Using Vichar is simple. Just swap out your current LLM provider URL with the Vichar API endpoint: ```bash curl -X POST https://api.vichar.io/v1/chat/completions \ -H "Content-Type: application/json" \ -H "Authorization: Bearer $LLM_GATEWAY_API_KEY" \ -d '{ "model": "gpt-4o", "messages": [ {"role": "user", "content": "Hello, how are you?"} ] }' ``` Vichar maintains compatibility with the OpenAI API format, making migration seamless. Note that unknown or unsupported request parameters (for example `stop`, `seed`, `logprobs`, or `logit_bias`) are accepted and silently ignored rather than rejected, so a request carrying them still succeeds — the parameter just has no effect. ## Hosted vs. Self-Hosted [#hosted-vs-self-hosted] You can use Vichar in two ways: * **Hosted Version**: For immediate use without setup, visit [app.vichar.io](https://app.vichar.io) to create an account and get an API key. * **Self-Hosted**: Deploy Vichar on your own infrastructure for complete control over your data and configuration. The self-hosted version offers additional customization options and ensures your LLM traffic never leaves your infrastructure if desired. # Quickstart URL: https://docs.vichar.io/quick-start Welcome to **Vichar**—a single drop‑in endpoint that lets you call today’s best large‑language models while keeping **your existing code** and development workflow intact. > **TL;DR** — Point your HTTP requests to `https://api.vichar.io/v1/…`, supply your `LLM_GATEWAY_API_KEY`, and you’re done. *** ## 1 · Get an API key [#1--get-an-api-key] 1. Sign in to the dashboard. 2. Create a new Project → *Copy the key*. 3. Export it in your shell (or a `.env` file): ```bash export LLM_GATEWAY_API_KEY="vichar_XXXXXXXXXXXXXXXX" ``` *** ## 2 · Pick your language [#2--pick-your-language] ```bash curl -X POST https://api.vichar.io/v1/chat/completions \ -H "Content-Type: application/json" \ -H "Authorization: Bearer $LLM_GATEWAY_API_KEY" \ -d '{ "model": "gpt-4o", "messages": [ {"role": "user", "content": "Hello, how are you?"} ] }' ``` ```typescript const response = await fetch("https://api.vichar.io/v1/chat/completions", { method: "POST", headers: { "Content-Type": "application/json", Authorization: `Bearer ${process.env.LLM_GATEWAY_API_KEY}`, }, body: JSON.stringify({ model: "gpt-4o", messages: [{ role: "user", content: "Hello, how are you?" }], }), }); if (!response.ok) { throw new Error(`HTTP error! status: ${response.status}`); } const data = await response.json(); console.log(data.choices[0].message.content); ``` ```tsx import { useState } from "react"; function ChatComponent() { const [response, setResponse] = useState(""); const [loading, setLoading] = useState(false); const sendMessage = async () => { setLoading(true); try { const res = await fetch("https://api.vichar.io/v1/chat/completions", { method: "POST", headers: { "Content-Type": "application/json", Authorization: `Bearer ${process.env.REACT_APP_LLM_GATEWAY_API_KEY}`, }, body: JSON.stringify({ model: "gpt-4o", messages: [{ role: "user", content: "Hello, how are you?" }], }), }); if (!res.ok) { throw new Error(`HTTP error! status: ${res.status}`); } const data = await res.json(); setResponse(data.choices[0].message.content); } catch (error) { console.error("Error:", error); } finally { setLoading(false); } }; return (
{response &&

{response}

}
); } export default ChatComponent; ```
```typescript // app/api/chat/route.ts import { NextRequest, NextResponse } from "next/server"; export async function POST(request: NextRequest) { const { message } = await request.json(); const response = await fetch("https://api.vichar.io/v1/chat/completions", { method: "POST", headers: { "Content-Type": "application/json", Authorization: `Bearer ${process.env.LLM_GATEWAY_API_KEY}`, }, body: JSON.stringify({ model: "gpt-4o", messages: [{ role: "user", content: message }], }), }); if (!response.ok) { return NextResponse.json( { error: "Failed to get response" }, { status: response.status }, ); } const data = await response.json(); return NextResponse.json({ message: data.choices[0].message.content, }); } // Usage in component: // const response = await fetch('/api/chat', { // method: 'POST', // headers: { 'Content-Type': 'application/json' }, // body: JSON.stringify({ message: 'Hello, how are you?' }) // }); ``` ```python import requests import os response = requests.post( 'https://api.vichar.io/v1/chat/completions', headers={ 'Content-Type': 'application/json', 'Authorization': f'Bearer {os.getenv("LLM_GATEWAY_API_KEY")}' }, json={ 'model': 'gpt-4o', 'messages': [ {'role': 'user', 'content': 'Hello, how are you?'} ] } ) response.raise_for_status() print(response.json()['choices'][0]['message']['content']) ``` ```java import java.net.http.HttpClient; import java.net.http.HttpRequest; import java.net.http.HttpResponse; import java.net.URI; String apiKey = System.getenv("LLM_GATEWAY_API_KEY"); String requestBody = """ { "model": "gpt-4o", "messages": [ {"role": "user", "content": "Hello, how are you?"} ] } """; HttpRequest request = HttpRequest.newBuilder() .uri(URI.create("https://api.vichar.io/v1/chat/completions")) .header("Content-Type", "application/json") .header("Authorization", "Bearer " + apiKey) .POST(HttpRequest.BodyPublishers.ofString(requestBody)) .build(); HttpResponse response = HttpClient.newHttpClient() .send(request, HttpResponse.BodyHandlers.ofString()); System.out.println(response.body()); ``` ```rust use reqwest::Client; use serde_json::json; use std::env; #[tokio::main] async fn main() -> Result<(), Box> { let client = Client::new(); let api_key = env::var("LLM_GATEWAY_API_KEY")?; let response = client .post("https://api.vichar.io/v1/chat/completions") .header("Content-Type", "application/json") .header("Authorization", format!("Bearer {}", api_key)) .json(&json!({ "model": "gpt-4o", "messages": [ {"role": "user", "content": "Hello, how are you?"} ] })) .send() .await?; let result: serde_json::Value = response.json().await?; println!("{}", result["choices"][0]["message"]["content"]); Ok(()) } ``` ```go package main import ( "bytes" "encoding/json" "fmt" "net/http" "os" ) type ChatRequest struct { Model string `json:"model"` Messages []Message `json:"messages"` } type Message struct { Role string `json:"role"` Content string `json:"content"` } func main() { apiKey := os.Getenv("LLM_GATEWAY_API_KEY") requestBody := ChatRequest{ Model: "gpt-4o", Messages: []Message{{Role: "user", Content: "Hello, how are you?"}}, } jsonData, _ := json.Marshal(requestBody) req, _ := http.NewRequest("POST", "https://api.vichar.io/v1/chat/completions", bytes.NewBuffer(jsonData)) req.Header.Set("Content-Type", "application/json") req.Header.Set("Authorization", "Bearer "+apiKey) client := &http.Client{} resp, _ := client.Do(req) defer resp.Body.Close() fmt.Println("Response received") } ``` ```php 'gpt-4o', 'messages' => [ ['role' => 'user', 'content' => 'Hello, how are you?'] ] ]; $options = [ 'http' => [ 'header' => [ 'Content-Type: application/json', 'Authorization: Bearer ' . $apiKey ], 'method' => 'POST', 'content' => json_encode($data) ] ]; $context = stream_context_create($options); $response = file_get_contents( 'https://api.vichar.io/v1/chat/completions', false, $context ); if ($response === FALSE) { throw new Exception('Request failed'); } $result = json_decode($response, true); echo $result['choices'][0]['message']['content']; ?> ``` ```ruby require 'net/http' require 'json' require 'uri' uri = URI('https://api.vichar.io/v1/chat/completions') http = Net::HTTP.new(uri.host, uri.port) http.use_ssl = true request = Net::HTTP::Post.new(uri) request['Content-Type'] = 'application/json' request['Authorization'] = "Bearer #{ENV['LLM_GATEWAY_API_KEY']}" request.body = { model: 'gpt-4o', messages: [ { role: 'user', content: 'Hello, how are you?' } ] }.to_json response = http.request(request) if response.code != '200' raise "HTTP Error: #{response.code}" end result = JSON.parse(response.body) puts result['choices'][0]['message']['content'] ```
*** ## 3 · SDK integrations [#3--sdk-integrations] ```ts title="ai-sdk.ts" import { llmgateway } from "@llmgateway/ai-sdk-provider"; import { generateText } from "ai"; const { text } = await generateText({ model: llmgateway("gpt-4o"), prompt: "Write a vegetarian lasagna recipe for 4 people.", }); ``` ```ts title="vercel-ai-sdk.ts" import { createOpenAI } from "@ai-sdk/openai"; const llmgateway = createOpenAI({ baseURL: "https://api.vichar.io/v1", apiKey: process.env.LLM_GATEWAY_API_KEY!, }); const completion = await llmgateway.chat({ model: "gpt-4o", messages: [{ role: "user", content: "Hello, how are you?" }], }); console.log(completion.choices[0].message.content); ``` ```ts title="openai-sdk.ts" import OpenAI from "openai"; const openai = new OpenAI({ baseURL: "https://api.vichar.io/v1", apiKey: process.env.LLM_GATEWAY_API_KEY, }); const completion = await openai.chat.completions.create({ model: "gpt-4o", messages: [{ role: "user", content: "Hello, how are you?" }], }); console.log(completion.choices[0].message.content); ``` *** ## 4 · Going further [#4--going-further] * **Streaming**: pass `stream: true` to any request—the gateway normalizes every provider's stream into OpenAI-format SSE chunks, with a final chunk carrying `usage` and routing metadata before `data: [DONE]`. * **Monitoring**: Every call appears in the dashboard with latency, cost & provider breakdown. *** ## 5 · FAQ [#5--faq] See the [Models page](https://app.vichar.io/dashboard).

Unlike OpenRouter, we offer:

Our pricing structure is designed to be flexible and cost-effective: See the [Pricing section](https://app.vichar.io#pricing).
*** ## 6 · Next steps [#6--next-steps] * Read [Self host docs](https://docs.vichar.io/self-host) guide. * Drop into our [GitHub](https://github.com/vicharai/api) for help or feature requests. Happy building! ✨ # Health check URL: https://docs.vichar.io/health {/* This file was generated by Fumadocs. Do not edit this file directly. Any changes should be made by running the generation command again. */} # Create speech URL: https://docs.vichar.io/v1_audio_speech {/* This file was generated by Fumadocs. Do not edit this file directly. Any changes should be made by running the generation command again. */} # Create transcription URL: https://docs.vichar.io/v1_audio_transcriptions {/* This file was generated by Fumadocs. Do not edit this file directly. Any changes should be made by running the generation command again. */} # Chat Completions URL: https://docs.vichar.io/v1_chat_completions {/* This file was generated by Fumadocs. Do not edit this file directly. Any changes should be made by running the generation command again. */} # Embeddings URL: https://docs.vichar.io/v1_embeddings {/* This file was generated by Fumadocs. Do not edit this file directly. Any changes should be made by running the generation command again. */} # Edit image URL: https://docs.vichar.io/v1_images_edits {/* This file was generated by Fumadocs. Do not edit this file directly. Any changes should be made by running the generation command again. */} # Create image URL: https://docs.vichar.io/v1_images_generations {/* This file was generated by Fumadocs. Do not edit this file directly. Any changes should be made by running the generation command again. */} # Retrieve key status URL: https://docs.vichar.io/v1_key_retrieve {/* This file was generated by Fumadocs. Do not edit this file directly. Any changes should be made by running the generation command again. */} # Anthropic Messages URL: https://docs.vichar.io/v1_messages {/* This file was generated by Fumadocs. Do not edit this file directly. Any changes should be made by running the generation command again. */} # Models URL: https://docs.vichar.io/v1_models {/* This file was generated by Fumadocs. Do not edit this file directly. Any changes should be made by running the generation command again. */} # Moderations URL: https://docs.vichar.io/v1_moderations {/* This file was generated by Fumadocs. Do not edit this file directly. Any changes should be made by running the generation command again. */} # OCR URL: https://docs.vichar.io/v1_ocr {/* This file was generated by Fumadocs. Do not edit this file directly. Any changes should be made by running the generation command again. */} # Create a realtime client secret URL: https://docs.vichar.io/v1_realtime_client_secrets {/* This file was generated by Fumadocs. Do not edit this file directly. Any changes should be made by running the generation command again. */} # Rerank URL: https://docs.vichar.io/v1_rerank {/* This file was generated by Fumadocs. Do not edit this file directly. Any changes should be made by running the generation command again. */} # System One URL: https://docs.vichar.io/v1_systemone {/* This file was generated by Fumadocs. Do not edit this file directly. Any changes should be made by running the generation command again. */} # Video content URL: https://docs.vichar.io/v1_videos_content {/* This file was generated by Fumadocs. Do not edit this file directly. Any changes should be made by running the generation command again. */} # Create video URL: https://docs.vichar.io/v1_videos_create {/* This file was generated by Fumadocs. Do not edit this file directly. Any changes should be made by running the generation command again. */} # Video log content URL: https://docs.vichar.io/v1_videos_log_content {/* This file was generated by Fumadocs. Do not edit this file directly. Any changes should be made by running the generation command again. */} # Retrieve video URL: https://docs.vichar.io/v1_videos_retrieve {/* This file was generated by Fumadocs. Do not edit this file directly. Any changes should be made by running the generation command again. */} # AI SDK Gateway protocol URL: https://docs.vichar.io/developers/ai-sdk-gateway-protocol When you pass a bare model string to the AI SDK — `streamText({ model: "anthropic/claude-sonnet-5" })` — the SDK resolves it through its **default provider**, `@ai-sdk/gateway`. That provider does not speak the OpenAI Chat Completions format: it has its own wire protocol, `LanguageModelV*CallOptions` in and `LanguageModelV*` parts out. Vichar implements that protocol, so an app written against the Vercel AI Gateway runs here with **no code change** — only its base URL and API key are repointed. ## Repoint the default provider [#repoint-the-default-provider] ```ts import { createGateway } from "@ai-sdk/gateway"; globalThis.AI_SDK_DEFAULT_PROVIDER = createGateway({ baseURL: "https://api.vichar.io/v4/ai", apiKey: process.env.LLM_GATEWAY_API_KEY, }); ``` Put this wherever your app runs before its first model call — a Next.js [`instrumentation.ts`](https://nextjs.org/docs/app/guides/instrumentation), a server entrypoint, or a platform-injected preamble. Every bare model string in the app then resolves through Vichar. `@ai-sdk/gateway` is already a transitive dependency of `ai`, so there is nothing extra to install. `@ai-sdk/gateway` reads its API key from `AI_GATEWAY_API_KEY` but has **no** environment variable for the base URL — it is a constructor option only. That is why repointing takes this one line rather than an env var. Or construct the provider explicitly and pass it per call: ```ts import { createGateway } from "@ai-sdk/gateway"; import { streamText } from "ai"; const gateway = createGateway({ baseURL: "https://api.vichar.io/v4/ai", apiKey: process.env.LLM_GATEWAY_API_KEY, }); const result = streamText({ model: gateway("anthropic/claude-sonnet-5"), prompt: "Hello!", }); ``` ## Base URL per AI SDK version [#base-url-per-ai-sdk-version] The protocol carries the language-model specification version in a request header, and every prefix below serves the same surface — pick the one matching the `@ai-sdk/gateway` your app has, so the default path stays intact: | AI SDK | Spec version | Base URL | | ------ | ------------ | ----------------------------- | | 5 | 2 | `https://api.vichar.io/v1/ai` | | 6 | 3 | `https://api.vichar.io/v3/ai` | | 7 | 4 | `https://api.vichar.io/v4/ai` | ## Model IDs [#model-ids] Model IDs use the provider-pinned `provider/model` form (`anthropic/claude-sonnet-5`, `openai/gpt-4o`) — the same convention AI Gateway IDs use, so existing model strings resolve unchanged. Vichar's smart-routing IDs work here too: pass a bare model ID (`gpt-4o`) to let the gateway pick a provider, or `auto` to let it pick the model. Those are not returned by `getAvailableModels()` because they do not name one provider, but they are accepted. ## Listing models [#listing-models] ```ts const { models } = await gateway.getAvailableModels(); ``` Returns one entry per active provider mapping, with pricing and an AI SDK `specification` block. This is what backs a model picker built on `GatewayModel[]`. ## Credits [#credits] ```ts const { balance, totalUsed } = await gateway.getCredits(); ``` `balance` is the organization's remaining credit balance and `totalUsed` its lifetime credits spend. ## Gateway-only options [#gateway-only-options] Features that have no field in the AI SDK call options — reasoning effort, service tier, routing strategy, prompt cache keys, plugins — are set through the `llmgateway` provider options namespace, which is passed onto the underlying request: ```ts const result = streamText({ model: gateway("openai/gpt-5.6-terra"), prompt: "Hello!", providerOptions: { llmgateway: { reasoning_effort: "high", routing: "price", }, }, }); ``` Any field the [chat completions API](https://docs.vichar.io/api-reference) accepts works here, except `model`, `messages` and `stream`, which this surface owns. ## Web search [#web-search] The provider-native web search tools serialize to provider-defined tools, and the gateway maps them onto its [native web search](https://docs.vichar.io/features/web-search): ```ts import { openai } from "@ai-sdk/openai"; const result = streamText({ model: gateway("openai/gpt-4o"), prompt: "What happened in the news today?", tools: { web_search: openai.tools.webSearch() }, }); ``` Recognised tools: `openai.web_search`, `openai.web_search_preview`, `anthropic.web_search_20250305`, `anthropic.web_search_20260209`, `google.google_search`. Search results come back as `source-url` message parts plus a provider-executed tool call under the name you bound the tool to, so the AI SDK's sources UI works unchanged. A provider-defined tool the gateway cannot map is reported as an `unsupported-tool` warning on the result rather than failing the request. ## What is not covered [#what-is-not-covered] This surface implements language models. Embeddings, images, video, speech, transcription, reranking and realtime are served by the [OpenAI-compatible endpoints](https://docs.vichar.io/api-reference) — use [`@llmgateway/ai-sdk-provider`](https://docs.vichar.io/developers/ai-sdk) for those. These call options have no chat completions equivalent and are reported as `unsupported` warnings: `stopSequences`, `seed`, `topK`. # Image Generation with the AI SDK URL: https://docs.vichar.io/developers/ai-sdk-images The `@llmgateway/ai-sdk-provider` package supports image generation both through the AI SDK's dedicated `generateImage` function and through chat-based image models that stream images as part of a conversation. ## generateImage [#generateimage] Use `llmgateway.image()` to get an image model: ```typescript import { createLLMGateway } from "@llmgateway/ai-sdk-provider"; import { generateImage } from "ai"; import { writeFileSync } from "fs"; const llmgateway = createLLMGateway({ apiKey: process.env.LLM_GATEWAY_API_KEY, }); const result = await generateImage({ model: llmgateway.image("gemini-3-pro-image"), prompt: "A cozy cabin in a snowy mountain landscape at night with aurora borealis", size: "1024x1024", n: 1, // aspectRatio and quality are model-specific — only some providers honor them. // aspectRatio works on Gemini image models; OpenAI gpt-image-2 ignores it // (use a literal WxH `size` instead). aspectRatio: "16:9", // quality works on OpenAI gpt-image-2 ("low" | "medium" | "high" | "auto") // and moderation ("auto" | "low") on GPT Image models. // The AI SDK only forwards these through providerOptions. providerOptions: { llmgateway: { quality: "high", moderation: "low" }, }, }); result.images.forEach((image, i) => { const buf = Buffer.from(image.base64, "base64"); writeFileSync(`image-${i}.png`, buf); }); ``` Which sizes, aspect ratios, and quality settings a model accepts depends on the model — see [Image Generation](https://docs.vichar.io/features/image-generation) for the full parameter reference and per-model behavior. ## Chat-based image models [#chat-based-image-models] Multimodal models like `gemini-3-pro-image` can return images inside a chat conversation. Use `llmgateway.chat()` with `streamText` in a route handler: ```typescript // app/api/chat/route.ts import { createLLMGateway } from "@llmgateway/ai-sdk-provider"; import { convertToModelMessages, streamText } from "ai"; const llmgateway = createLLMGateway({ apiKey: process.env.LLM_GATEWAY_API_KEY, }); export async function POST(req: Request) { const { messages } = await req.json(); const result = streamText({ model: llmgateway.chat("gemini-3-pro-image"), messages: convertToModelMessages(messages), }); return result.toUIMessageStreamResponse(); } ``` On the client, image parts arrive as message file parts that you can render with the AI Elements `Image` component or a plain `` tag with a data URL. See [Image Generation](https://docs.vichar.io/features/image-generation) for the complete `useChat` frontend example. ## Video and audio [#video-and-audio] The AI SDK does not yet cover the gateway's video and speech endpoints — call them over REST instead: * [Video Generation](https://docs.vichar.io/features/video-generation) — `POST /v1/videos` (async jobs with optional signed callbacks) * [Speech Generation](https://docs.vichar.io/features/speech-generation) — `POST /v1/audio/speech` * [Transcription](https://docs.vichar.io/features/transcription) — `POST /v1/audio/transcriptions` # Using the AI SDK URL: https://docs.vichar.io/developers/ai-sdk Vichar ships a first-party provider for the [Vercel AI SDK](https://ai-sdk.dev): [`@llmgateway/ai-sdk-provider`](https://github.com/vicharai/api-ai-sdk-provider). One provider instance and one API key reach every model in the catalog. ## Install [#install] ```bash pnpm add ai @llmgateway/ai-sdk-provider ``` Set your API key (create one from the [dashboard](https://app.vichar.io/dashboard)): ```bash export LLM_GATEWAY_API_KEY=vichar_your_key_here ``` ## Generate text [#generate-text] ```typescript import { createLLMGateway } from "@llmgateway/ai-sdk-provider"; import { generateText } from "ai"; const llmgateway = createLLMGateway({ apiKey: process.env.LLM_GATEWAY_API_KEY, }); const { text } = await generateText({ model: llmgateway("openai/gpt-4o"), prompt: "Hello!", }); ``` Switching models is a one-line change — the same provider serves every model: ```typescript const { text } = await generateText({ model: llmgateway("anthropic/claude-3-5-sonnet-20241022"), prompt: "Hello!", }); ``` ## Model ID formats [#model-id-formats] Vichar supports two model ID formats: * **Canonical model IDs** (`gpt-4o`) — smart routing picks the best provider based on uptime, throughput, price, and latency * **Provider-prefixed IDs** (`openai/gpt-4o`) — routes to a specific provider with automatic failover if uptime drops below 90% See the [routing documentation](https://docs.vichar.io/features/routing) for details and the [models page](https://app.vichar.io/dashboard) for the full catalog. ## Stream responses [#stream-responses] ```typescript import { createLLMGateway } from "@llmgateway/ai-sdk-provider"; import { streamText } from "ai"; const llmgateway = createLLMGateway({ apiKey: process.env.LLM_GATEWAY_API_KEY, }); const { textStream } = await streamText({ model: llmgateway("anthropic/claude-3-5-sonnet-20241022"), prompt: "Write a poem about coding", }); for await (const text of textStream) { process.stdout.write(text); } ``` ## Next.js route handler [#nextjs-route-handler] ```typescript // app/api/chat/route.ts import { createLLMGateway } from "@llmgateway/ai-sdk-provider"; import { streamText } from "ai"; const llmgateway = createLLMGateway({ apiKey: process.env.LLM_GATEWAY_API_KEY, }); export async function POST(req: Request) { const { messages } = await req.json(); const result = await streamText({ model: llmgateway("openai/gpt-4o"), messages, }); return result.toDataStreamResponse(); } ``` ## Tool calling [#tool-calling] ```typescript import { createLLMGateway } from "@llmgateway/ai-sdk-provider"; import { generateText, tool } from "ai"; import { z } from "zod"; const llmgateway = createLLMGateway({ apiKey: process.env.LLM_GATEWAY_API_KEY, }); const { text, toolResults } = await generateText({ model: llmgateway("openai/gpt-4o"), tools: { weather: tool({ description: "Get the weather for a location", parameters: z.object({ location: z.string(), }), execute: async ({ location }) => { return { temperature: 72, condition: "sunny" }; }, }), }, prompt: "What's the weather in San Francisco?", }); ``` ## Without the provider package [#without-the-provider-package] If you prefer not to add a dependency, point `@ai-sdk/openai` at the gateway with a custom base URL: ```typescript import { createOpenAI } from "@ai-sdk/openai"; import { generateText } from "ai"; const llmgateway = createOpenAI({ baseURL: "https://api.vichar.io/v1", apiKey: process.env.LLM_GATEWAY_API_KEY, }); const { text } = await generateText({ model: llmgateway("openai/gpt-4o"), prompt: "Hello!", }); ``` Every request made through the AI SDK shows up in your [Activity](https://docs.vichar.io/learn/activity) and [Usage & Metrics](https://docs.vichar.io/learn/usage-metrics) dashboards like any other gateway request — with per-request cost, tokens, and latency. ## Generate video [#generate-video] Version 4 of the provider (AI SDK 7, Node.js 22 or later, ESM) adds `llmgateway.video()` for the SDK's experimental video API. The provider submits a gateway video job, the SDK polls it, and the finished file is downloaded from the authenticated content endpoint. ```typescript import { writeFile } from "node:fs/promises"; import { llmgateway } from "@llmgateway/ai-sdk-provider"; import { experimental_generateVideo as generateVideo } from "ai"; const { video } = await generateVideo({ model: llmgateway.video("seedance-2-0"), prompt: "A cinematic aerial view of ocean waves at sunrise", duration: 8, resolution: "1280x720", poll: { intervalMs: 5_000, timeoutMs: 600_000 }, }); await writeFile("video.mp4", video.uint8Array); ``` `duration` and a text prompt are required. `resolution` maps to the gateway's `size`, `duration` to `seconds`, and `generateAudio` to `audio`. Pass a first frame as `prompt.image`, first and last frames with `frameImages`, and reference inputs with `inputReferences`; any other gateway field, such as `callback_url`, goes through `providerOptions.llmgateway`. `experimental_startVideo` and `experimental_getVideoStatus` let another process pick up a running job. Supported sizes, durations, and inputs depend on the model — see [video generation](https://docs.vichar.io/features/video-generation) for the REST reference. Projects on AI SDK 6 should stay on `@llmgateway/ai-sdk-provider@3`, which has no video support. ## Next steps [#next-steps] * [Image generation with the AI SDK](https://docs.vichar.io/developers/ai-sdk-images) * [Migrate from Vercel AI Gateway](https://docs.vichar.io/migrations/vercel-ai-gateway) * [Reasoning support](https://docs.vichar.io/features/reasoning) and [caching](https://docs.vichar.io/features/caching) # Vichar CLI URL: https://docs.vichar.io/developers/cli The **Vichar CLI** (`@llmgateway/cli`) is a command-line utility for launching coding agents pre-configured with Vichar, scaffolding projects, discovering models, and managing your Vichar account — API keys, spending budgets, and usage analytics — straight from the terminal. ## Installation [#installation] Run commands directly without installation: ```bash npx @llmgateway/cli init ``` Install globally for faster access: ```bash npm install -g @llmgateway/cli ``` Then run commands directly (`lg` works as a shorthand alias): ```bash llmgateway init lg init ``` ## Quick Start [#quick-start] ### Initialize a Project [#initialize-a-project] Create a new project from a template: ```bash npx @llmgateway/cli init ``` Or specify the template and name directly: ```bash npx @llmgateway/cli init --template image-generation --name my-ai-app ``` ### Sign In [#sign-in] Sign in with your Vichar account to unlock key management, budgets, and usage analytics: ```bash npx @llmgateway/cli auth login --email you@example.com ``` Or store a gateway API key only (enough for making gateway requests): ```bash npx @llmgateway/cli auth login --key ``` Credentials are stored in `~/.llmgateway/config.json`. The `LLMGATEWAY_API_KEY` environment variable takes precedence over a stored key. ### Start Development [#start-development] Navigate to your project and start the development server: ```bash cd my-ai-app npx @llmgateway/cli dev ``` Or specify a custom port: ```bash npx @llmgateway/cli dev --port 3000 ``` ## Launch Coding Agents [#launch-coding-agents] ### `launch` [#launch] Start any supported coding agent pre-wired to Vichar: one API key, 200+ models, and every request tracked in your [dashboard](https://app.vichar.io/dashboard). ```bash # Interactive agent picker npx @llmgateway/cli launch # Launch a specific agent (shortcuts work too: `llmgateway claude`) npx @llmgateway/cli launch claude npx @llmgateway/cli launch opencode npx @llmgateway/cli launch codex # Pick a model — launcher flags go before the agent name npx @llmgateway/cli launch -m gpt-5.5 claude # Everything after the agent name is passed to the agent itself npx @llmgateway/cli launch claude --continue # List all supported agents and see which are installed npx @llmgateway/cli launch --list # Inspect what would run without launching npx @llmgateway/cli launch --dry-run codex ``` Every supported agent also works as a direct shortcut, e.g. `npx @llmgateway/cli claude`. The launcher configures each agent automatically — environment variables, config files, or the agent's own key-registration command, whichever that agent needs — without overwriting your existing setup. For OpenCode and Claude Code, launching also applies the same model-catalog setup as [`configure`](#configure) on every launch, so their model pickers stay fresh as new models ship. The API key is resolved from `--key`, the `LLMGATEWAY_API_KEY` environment variable, or the key stored by `llmgateway auth login --key` — in that order. Before launching, the key is verified against the gateway; a stale key (e.g. one you rolled or deleted) is reported with its exact source and the launcher falls back to the next valid one, prompting you for a fresh key if none works. If an agent isn't installed, the launcher prints its official install command and exits. See the [integration guides](https://app.vichar.io/dashboard) for per-agent setup details, and run `npx @llmgateway/cli launch --list` for the up-to-date list of supported agents. ### `configure` [#configure] Put Vichar's coding-model catalog directly into an agent's own config, so its model picker lists gateway models without launching through the CLI: ```bash # opencode: adds every coding model, pinned per upstream provider, to the picker npx @llmgateway/cli configure opencode # Claude Code: routes it through Vichar and fills /model from the gateway catalog npx @llmgateway/cli configure claude # ...for the current repo only (.claude/settings.local.json) npx @llmgateway/cli configure claude --project # Preview without writing npx @llmgateway/cli configure opencode --dry-run ``` * **OpenCode** — merges `provider/model` entries (e.g. `anthropic/claude-sonnet-5`, `aws-bedrock/claude-sonnet-5`) into `provider.llmgateway.models` in `~/.config/opencode/opencode.json`, with display names, context limits, and per-provider pricing. They show up in the picker as `llmgateway//` and pin that upstream provider via the gateway's [provider-routing syntax](https://docs.vichar.io/features/routing#provider-specific-routing). OpenCode now ships both catalogs natively too — canonical IDs under **Vichar** (`llmgateway`) and pinned `provider/model` IDs under **Vichar (provider-pinned)** (`llmgateway-providers`) — so `configure` mainly covers models the built-in catalog has not picked up yet. Existing custom entries and the rest of the file are preserved, and a hand-written `opencode.jsonc` keeps working alongside it. * **Claude Code** — sets `ANTHROPIC_BASE_URL`, `ANTHROPIC_AUTH_TOKEN`, and `CLAUDE_CODE_ENABLE_GATEWAY_MODEL_DISCOVERY=1` in `~/.claude/settings.json` (requires Claude Code v2.1.129+). Claude Code then loads the gateway's `/v1/models` catalog into its `/model` picker (shown as "From gateway"). Claude Code only lists IDs starting with `claude`/`anthropic`; any other gateway model still works via `claude --model `. `llmgateway launch opencode` and `llmgateway launch claude` apply the same setup automatically on every launch, keeping the catalog fresh as new models ship. ## Project Commands [#project-commands] ### `init` [#init] Initialize a new project from a template. ```bash npx @llmgateway/cli init [directory] [options] ``` **Options:** * `-t, --template ` — Template to use (default: `image-generation`) * `-n, --name ` — Project name **Examples:** ```bash # Interactive mode npx @llmgateway/cli init # With options npx @llmgateway/cli init --template image-generation --name my-app ``` ### `list` [#list] Display available project templates, grouped by category. Alias: `ls`. ```bash npx @llmgateway/cli list ``` **Options:** * `--json` — Output in JSON format ### `models` [#models] Browse and filter available AI models. ```bash npx @llmgateway/cli models [options] ``` **Options:** * `-c, --capability ` — Filter by capability (e.g., `image`, `text`) * `-p, --provider ` — Filter by provider (e.g., `openai`, `anthropic`) * `-s, --search ` — Search models by name * `--json` — Output in JSON format **Examples:** ```bash # List all models npx @llmgateway/cli models # Filter by provider npx @llmgateway/cli models --provider openai # Search models npx @llmgateway/cli models --search gpt ``` ### `add` [#add] Add tools or API routes to an existing project. ```bash npx @llmgateway/cli add [type] [name] ``` Runs interactively when `type` (`tool` or `route`) and `name` are omitted. **Tools available:** * `weather` — Weather lookup functionality * `search` — Web search capability * `calculator` — Mathematical operations **API routes available:** * `generate` — Text generation endpoint * `chat` — Chat completion endpoint with streaming ### `dev` [#dev] Start the local development server using your project's package manager. ```bash npx @llmgateway/cli dev [options] ``` **Options:** * `-p, --port ` — Port to run on ### `upgrade` [#upgrade] Update Vichar dependencies (`@llmgateway/ai-sdk-provider`, `@llmgateway/models`, `@llmgateway/cli`) in your project. ```bash npx @llmgateway/cli upgrade [options] ``` **Options:** * `--check` — Check for updates without installing ### `docs` [#docs] Open the documentation in your browser. ```bash npx @llmgateway/cli docs [topic] ``` **Topics:** `models`, `api`, `sdk`, `quickstart` — omit to open the docs home and see all topics. ## Account Commands [#account-commands] The commands below require a dashboard session — sign in first with `llmgateway auth login --email`. A gateway API key alone is not enough for account management. ### `auth` [#auth] Manage authentication (dashboard session and gateway API key). For browser-based device sign-in, the approval page is titled **Authorize your device**. Check that its code matches the one on your device before choosing **Authorize device**. Approval creates a separate account session; signing the device out leaves the browser signed in. Choose **Deny** for a request you did not start. ```bash # Sign in with email & password (full access), or paste an API key npx @llmgateway/cli auth login npx @llmgateway/cli auth login --email you@example.com npx @llmgateway/cli auth login --key # Check authentication status (session + API key) npx @llmgateway/cli auth status # Show the signed-in user npx @llmgateway/cli auth whoami # Remove stored session and API key npx @llmgateway/cli auth logout ``` ### `keys` [#keys] Create and manage gateway API keys. ```bash npx @llmgateway/cli keys ``` #### `keys create` [#keys-create] Create a new API key, optionally with spending limits and an expiry. ```bash npx @llmgateway/cli keys create --description "CI key" --limit 100 --expires 30d ``` **Options:** * `-p, --project ` — Project the key belongs to * `-d, --description ` — Key description * `-l, --limit ` — Total spending limit in USD (e.g. `100` or `49.99`) * `--period-limit ` — Spending limit per rolling period in USD * `--period ` — Rolling period for `--period-limit` (`12h`, `1d`, `2w`, `1mo`; default `1mo`) * `-e, --expires ` — TTL as a duration (`30d`, `12h`) or an ISO date * `--json` — Output in JSON format The token is only displayed once at creation time — save it immediately. #### `keys list` [#keys-list] List API keys with spend, budget, and expiry. Alias: `keys ls`. **Options:** * `-p, --project ` — Filter by project * `--all` — Show all keys in the org (admin/owner only) * `--json` — Output in JSON format #### `keys update ` [#keys-update-id] Activate or deactivate an API key. **Options:** * `--activate` — Set the key to active * `--deactivate` — Set the key to inactive * `-e, --expires ` — New expiry as a duration (`30d`) or ISO date (needed to reactivate expired keys) #### `keys limit ` [#keys-limit-id] Set spending limits on an API key (same as `budget set`). **Options:** * `-l, --limit ` — Total spending limit in USD * `--period-limit ` — Spending limit per rolling period in USD * `--period ` — Rolling period (`12h`, `1d`, `2w`, `1mo`; default `1mo`) * `--clear` — Remove all spending limits #### `keys roll ` [#keys-roll-id] Regenerate the token for an API key. The old token becomes invalid immediately. **Options:** * `-y, --yes` — Skip confirmation #### `keys delete ` [#keys-delete-id] Delete an API key. Alias: `keys rm`. **Options:** * `-y, --yes` — Skip confirmation ### `budget` [#budget] Manage API key spending limits. ```bash # Set a total and/or rolling-period budget npx @llmgateway/cli budget set --limit 100 --period-limit 25 --period 1w # Remove all spending limits npx @llmgateway/cli budget set --clear # Show budget and current spend npx @llmgateway/cli budget get ``` **`budget set` options:** `-l, --limit `, `--period-limit `, `--period `, `--clear` **`budget get` options:** `-p, --project `, `--json` ### `usage` [#usage] View usage and cost analytics. ```bash npx @llmgateway/cli usage [options] ``` **Options:** * `-o, --org ` — Aggregate usage across an organization * `-p, --project ` — Filter by project * `-k, --api-key ` — Filter by API key * `--by ` — Break down by `model` or `key` * `-r, --range ` — Time range: `1h`, `4h`, `24h`, `7d`, `30d`, `365d` (default `7d`) * `--days ` — Look back N days instead of `--range` * `--from ` / `--to ` — Custom date range (`YYYY-MM-DD`) * `--json` — Output in JSON format **Examples:** ```bash # Last 7 days for the default project npx @llmgateway/cli usage # Cost per model over the last 30 days npx @llmgateway/cli usage --by model --range 30d # Whole-org aggregate npx @llmgateway/cli usage --org ``` #### `usage sources` [#usage-sources] Break down usage by session/agent source to see which agents or sessions are spending. ```bash npx @llmgateway/cli usage sources [options] ``` **Options:** `-p, --project `, `-r, --range ` (`7d`, `30d`), `--from `, `--to `, `--json` ### `orgs` [#orgs] List your organizations with plan and credit balance. Alias: `orgs ls`. ```bash npx @llmgateway/cli orgs list [--json] ``` ### `projects` [#projects] Manage projects and the CLI's default project. ```bash # List projects (optionally filtered by org) npx @llmgateway/cli projects list [--org ] [--json] # Set the default project used by keys/budget/usage commands npx @llmgateway/cli projects use ``` ### `credits` [#credits] Show organization credit balances. ```bash npx @llmgateway/cli credits [--org ] [--json] ``` ## Available Templates [#available-templates] ### Web Applications [#web-applications] * **`image-generation`** — Full-stack AI image generation app (Next.js 16, React 19). Multi-provider support with a unified API. * **`ai-chatbot`** — AI chatbot with streaming responses. * **`og-image-generator`** — AI-powered OG image generator. * **`feedback-dashboard`** — Customer feedback sentiment dashboard. * **`writing-assistant`** — AI writing assistant with text actions. * **`qa-agent`** — AI-powered QA testing agent with browser automation, real-time action timeline, and live browser preview. * **`showcase`** — Public, filterable gallery of apps built with Vichar templates. Static and deployable, with a "Submit your app" flow. ### Bots [#bots] * **`slack-qa-bot`** — Slack bot that streams AI answers and keeps thread context. ### CLI Agents [#cli-agents] * **`weather-agent`** — Answers weather queries using tool calling. * **`lead-agent`** — Researches people and posts results to Discord. * **`changelog-generator-agent`** — Generates changelogs from git history. * **`email-drafter-agent`** — Drafts polished emails from rough notes. * **`sentiment-analyzer-agent`** — Analyzes text sentiment. * **`data-extractor-agent`** — Extracts structured entities from text. ```bash npx @llmgateway/cli init --template qa-agent ``` ## Configuration [#configuration] The CLI stores configuration in `~/.llmgateway/config.json`: ```json { "apiKey": "vichar_...", "defaultTemplate": "image-generation", "sessionEmail": "you@example.com", "defaultOrgId": "org_...", "defaultProjectId": "proj_..." } ``` Signing in with `auth login --email` also stores a dashboard session used by the account commands (`keys`, `budget`, `usage`, `orgs`, `projects`, `credits`). ### Environment Variables [#environment-variables] * `LLMGATEWAY_API_KEY` — Gateway API key; takes precedence over the config file: ```bash export LLMGATEWAY_API_KEY="vichar_..." ``` * `LLMGATEWAY_API_URL` — Override the management API base URL (defaults to `https://api.vichar.io`), useful for self-hosted deployments. ## More Resources [#more-resources] * [GitHub Repository](https://github.com/vicharai/api-templates) — Source code and issues Need help or want to request a feature? Open an issue on [GitHub](https://github.com/vicharai/api-templates/issues). # Vichar Developer Resources URL: https://docs.vichar.io/developers This section is for developers building applications on top of Vichar — with our command-line tool, the MCP server, the [Vercel AI SDK](https://ai-sdk.dev) via our first-party provider package [`@llmgateway/ai-sdk-provider`](https://github.com/vicharai/api-ai-sdk-provider), and [TanStack AI](https://tanstack.com/ai) via the first-party [`@tanstack/ai-llmgateway`](https://www.npmjs.com/package/@tanstack/ai-llmgateway) adapter. ## API entry points [#api-entry-points] * [OpenAPI specification](https://api.vichar.io/openapi.json) — typed request, response, and error schemas * [Authentication](https://docs.vichar.io/features/api-keys) — API keys and access control * [Developer dashboard](https://app.vichar.io/dashboard) — projects, keys, usage, and budgets * [API versioning and deprecation policy](https://docs.vichar.io/resources/api-versioning) — compatibility and retirement notices ## Guides [#guides] * [**Vichar CLI**](https://docs.vichar.io/developers/cli) — Launch coding agents, scaffold projects from templates, generate agent configs, and manage keys, budgets, and usage from the terminal * [**Model Context Protocol (MCP)**](https://docs.vichar.io/developers/mcp) — Use Vichar as an MCP server from Claude Code, Cursor, and other MCP clients * [**Using the AI SDK**](https://docs.vichar.io/developers/ai-sdk) — Install the provider, generate and stream text, call tools, and wire up Next.js routes * [**Image Generation with the AI SDK**](https://docs.vichar.io/developers/ai-sdk-images) — Generate images with `generateImage` and stream image output through chat * [**Using TanStack AI**](https://docs.vichar.io/developers/tanstack-ai) — Stream chat with `useChat`, call tools, and surface reasoning through the first-party `@tanstack/ai-llmgateway` adapter ## Why the AI SDK [#why-the-ai-sdk] The AI SDK gives you one TypeScript interface for text generation, streaming, tool calling, and image generation. Combined with Vichar, a single provider instance and one API key reach every model in the catalog — see the [models page](https://app.vichar.io/dashboard) for what's available. ## Other ways to integrate [#other-ways-to-integrate] If you're not using the AI SDK: * Use any OpenAI-compatible SDK against `https://api.vichar.io/v1` — see the [Quickstart](https://docs.vichar.io/quick-start) * Use the Anthropic SDK against the [Anthropic-compatible endpoint](https://docs.vichar.io/features/anthropic-endpoint) * Call the REST API directly — see the API reference in the sidebar ## Brand assets [#brand-assets] For integration listings, presentations, and partner pages, download the official \[Vichar brand assets] in SVG or transparent PNG. The brand guide covers the horizontal logo, standalone symbol, clear space, minimum sizes, background colors, and typography. # Vichar MCP Server URL: https://docs.vichar.io/developers/mcp Connect your AI assistant to Vichar to inspect your usage and costs, discover your most-used models, providers and coding apps, and generate text or images. The same API key connects all of these tools. ## Video walkthrough [#video-walkthrough]