Documentation
Paste this into Claude Code, Cursor, or any coding agent to have it wire up the Viro API in your project for you.
I want to integrate the Viro API into this project — an OpenAI-compatible AI inference API that only routes to verified-renewable or renewable-matched compute providers.
Key facts:
- Base URL: https://api.viro.app/v1
- Auth: standard Bearer token — Authorization: Bearer <VIRO_API_KEY>
- It is a drop-in replacement for the OpenAI SDK: only base_url, api_key, and model change. Nothing else about how the SDK is called should need to change.
- Get an API key from https://console.viro.app/api-keys (starts with viro_sk_live_ or viro_sk_test_). Never hardcode it — read it from an environment variable (e.g. VIRO_API_KEY).
- Endpoints: POST /v1/chat/completions (streaming and non-streaming, tool calling, structured outputs), POST /v1/embeddings, POST /v1/images/generations, GET /v1/models.
- Server tools: add {"type": "viro:web_search"}, {"type": "viro:web_fetch"} and/or {"type": "viro:datetime"} to the `tools` array and Viro runs them server-side mid-completion — no tool loop needed in your code, works on every model. web_search is 1c/search; web_fetch and datetime are free. Failed tool calls are not billed. Works with stream: true — the tool rounds are spliced into the one client stream, and optional progress frames arrive as {"choices": [], "viro": {"tool_status": {...}}}, which standard SDKs ignore.
- Model routing (the recommended way to pick a model): instead of a concrete model slug, pass a router slug and Viro selects a real model per request — viro/clean (recommended default; restricted to renewable-verified providers, and errors rather than falling back to unverified infrastructure), viro/optimized (cheapest model that still clears the task's quality bar, across the whole catalog), viro/frontier (strongest available model, cost and energy disregarded). Same request and response shape; the model that actually ran comes back in the x-viro-router, x-viro-resolved-model and x-viro-provider response headers. Billing is at the resolved model's normal rate — routing itself costs nothing.
- Model IDs are prefixed by where they run: viro/* for Viro-routed open-weight models (e.g. viro/gpt-oss-120b, viro/qwen3-235b-instruct), or <lab>/* for frontier models routed straight through (openai/gpt-5.6-terra, anthropic/claude-sonnet-5, google/gemini-3.6-flash, xai/grok-4.3, etc). Call GET /v1/models for the current full list rather than assuming one.
- Every response includes an additive "viro" object (extra field — safe to ignore, useful to surface): {"viro": {"request_id": "...", "renewable_verified": true, "energy_source": "...", "inference_provider": "...", "zdr": true}}. zdr is true only for Viro-hosted open-weight models (Nscale/TensorX) — frontier lab models (openai/anthropic/google/xai) are false by default.
- Errors use OpenAI's error envelope: {"error": {"message": "...", "type": "...", "code": "..."}}. Handle 402 insufficient_quota and 429 rate_limit_exceeded distinctly from other 4xx/5xx.
Please:
1. Add VIRO_API_KEY as an environment variable (.env / secrets manager as appropriate for this project) — do not commit it or hardcode it.
2. Install the official OpenAI SDK for this project's language if it isn't already a dependency.
3. Configure the client with base_url="https://api.viro.app/v1" and api_key from that environment variable.
4. Default to the viro/clean router unless this use case needs a specific model — then pick a concrete slug (ask me if it's unclear which one).
5. Keep existing streaming / tool-calling / structured-output logic as-is — it should work unmodified since Viro speaks the same OpenAI wire format.1. Create an API key
Go to API Keys and create one. The full secret is shown once — copy it somewhere safe.
2. Check your credit
New accounts start with $0.25, a few hundred requests on the smaller models. It works everywhere — the API and the Playground. Top up from Billing ($5 minimum) when you run out.
3. Install the OpenAI SDK
pip install openai
# or
npm install openai4. Point it at Viro
from openai import OpenAI
client = OpenAI(
api_key="viro_sk_live_...",
base_url="https://api.viro.app/v1",
)
response = client.chat.completions.create(
model="viro/gpt-oss-120b",
messages=[{"role": "user", "content": "Explain photosynthesis."}],
)
print(response.choices[0].message.content)
print(response.viro) # renewable provenance for this request5. Models
See Models for the full live catalog with pricing, or call GET /v1/models directly. viro/* slugs are Viro-routed open-weight models; <lab>/* slugs (openai/, anthropic/, google/, xai/) are frontier models routed straight through to that lab.
Guides
Messages, streaming, tool calling, structured outputs.
Let Viro pick the model per request — clean, optimized, or frontier.
Generate vector embeddings from text.
Generate images from a text prompt.
Let the model search the web and fetch pages mid-request.
Which models cache a repeated prefix, and what it saves.
Wire Viro into OpenCode, OpenClaw, Cursor, and more.
Every error code the API can return and what to do about it.