Skip to main content
Welcome to the Michi Developer Guide! Michi provides unified access, smart routing, authentication, and comprehensive telemetry for all major LLM providers. This guide outlines the integration architecture, key scopes, and gateway behaviors you should understand when building on Michi.

Integration Flow

The diagram below shows how a completions request flows from your application through the Michi Gateway.

API Keys and Scopes

To isolate analytics and enforce strict budget splits across different systems, Michi supports three distinct API Key classifications:

Developer Keys

Assigned to human developers for building and local testing. Ideal for dev environments.

Application Keys

Bound to backend microservices and production environments. Optimized for high-throughput pipelines.

AI Agent Keys

Assigned to autonomous systems, background tasks, or AI agents that perform loops.

Language Integrations

Michi fits directly into your existing OpenAI SDK setup. Simply change the baseURL (or base_url) to https://api.michiai.co and provide your Michi API Key.

💻 Javascript / Node.js

import OpenAI from "openai";

const client = new OpenAI({
  apiKey: process.env.MICHI_API_KEY,
  baseURL: "https://api.michiai.co"
});

async function run() {
  const completion = await client.chat.completions.create({
    model: "openai/gpt-4o-mini", // Specify provider/model
    messages: [{ role: "user", content: "Hello from Node.js!" }]
  });

  console.log(completion.choices[0].message.content);
}

run();

🐍 Python

import os
from openai import OpenAI

client = OpenAI(
    api_key=os.environ.get("MICHI_API_KEY"),
    base_url="https://api.michiai.co"
)

response = client.chat.completions.create(
    model="claude/claude-3-5-sonnet",
    messages=[
        {"role": "user", "content": "Hello from Python!"}
    ]
)

print(response.choices[0].message.content)

🐹 Go

package main

import (
	"context"
	"fmt"
	"os"

	"github.com/sashabaranov/go-openai"
)

func main() {
	config := openai.DefaultConfig(os.Getenv("MICHI_API_KEY"))
	config.BaseURL = "https://api.michiai.co"

	client := openai.NewClientWithConfig(config)
	resp, err := client.CreateChatCompletion(
		context.Background(),
		openai.ChatCompletionRequest{
			Model: "deepseek/deepseek-v3",
			Messages: []openai.ChatCompletionMessage{
				{
					Role:    openai.ChatMessageRoleUser,
					Content: "Hello from Go!",
				},
			},
		},
	)

	if err != nil {
		fmt.Printf("Error: %v\n", err)
		return
	}

	fmt.Println(resp.Choices[0].Message.Content)
}

🛠️ CLI / Curl

curl -X POST https://api.michiai.co/chat/completions \
  -H "Authorization: Bearer $MICHI_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "auto",
    "messages": [
      {
        "role": "user",
        "content": "Hi! Pick the most cost-effective model."
      }
    ]
  }'

Dynamic Fallbacks

When you configure a Routing Policy in the dashboard, you specify a primary model and a sequence of fallback models. If the primary provider experiences rate limits (HTTP 429), timeouts, or service outages, the gateway automatically failovers and routes the request to the next backup model in your allowed chain. The client application receives a single, uninterrupted response.

Budgets and Rate Limits

To prevent runaway costs from looping scripts or unauthorized key usage, policies let you enforce strict guards at the key level:
  • Daily and Monthly Budgets: Set spending thresholds in USD. Once a key reaches its limit, the gateway rejects subsequent requests with an HTTP 403 Forbidden error.
  • TPM (Tokens-Per-Minute): Throttle maximum token throughput per minute to stay within provider limits.
  • RPM (Requests-Per-Minute): Throttle request frequency to protect backend models from congestion.