Skip to content

LangChain

MirAPI exposes an OpenAI-compatible endpoint, so LangChain’s ChatOpenAI class works with it directly — no dedicated integration package required. Point base_url at MirAPI and call any chat model from the catalogue, such as deepseek-chat.

Element Value
Base URL https://api.mirapi.ai/v1
API key sk-... (set as MIRAPI_API_KEY)
Model deepseek-chat
Terminal window
pip install langchain-openai
Terminal window
npm install @langchain/openai

Python:

import os
from langchain_openai import ChatOpenAI
llm = ChatOpenAI(
base_url="https://api.mirapi.ai/v1",
api_key=os.environ["MIRAPI_API_KEY"],
model="deepseek-chat",
)

TypeScript:

import { ChatOpenAI } from "@langchain/openai";
const llm = new ChatOpenAI({
model: "deepseek-chat",
apiKey: process.env.MIRAPI_API_KEY,
configuration: {
baseURL: "https://api.mirapi.ai/v1",
},
});
response = llm.invoke("Reply with exactly: connected to MirAPI")
print(response.content)

The output should contain connected to MirAPI.

for chunk in llm.stream("Count from 1 to 5."):
print(chunk.content, end="")
const stream = await llm.stream("Count from 1 to 5.");
for await (const chunk of stream) {
process.stdout.write(chunk.content as string);
}

Streaming uses standard SSE and ends with data: [DONE], which LangChain handles for you.

from langchain_core.tools import tool
@tool
def add(a: int, b: int) -> int:
"""Add two integers."""
return a + b
llm_with_tools = llm.bind_tools([add])
response = llm_with_tools.invoke("What is 3 + 5?")
print(response.tool_calls)

bind_tools maps to the OpenAI tools/tool_choice format. The model must support tool calling — check its capability flag in the model catalogue.

from pydantic import BaseModel
class Recipe(BaseModel):
name: str
ingredients: list[str]
structured = llm.with_structured_output(Recipe)
recipe = structured.invoke("Suggest a simple pasta recipe")
print(recipe)

Structured output maps to response_format (json_schema / JSON mode). The model must support JSON output.

Parameter Purpose
model Model id, verbatim from GET /v1/models
temperature Sampling temperature
max_tokens Cap on output tokens
streaming Enable SSE streaming
reasoning_effort Reasoning intensity (reasoning-capable models)
response_format Structured output (JSON mode / JSON Schema)
tools / tool_choice Tool calling

Reasoning tokens are billed as output. Prompt caching is automatic for OpenAI-compatible models, and cache reads are cheaper than regular input.

Status Meaning Action
401 Missing, invalid, or unknown key Fix the API key
403 Key valid but rejected (empty balance, model whitelist, quota, IP allowlist) Resolve the cause, then retry
413 Payload too large Reduce the request size
429 Rate limited — no Retry-After header Jittered exponential backoff: 1s → 2s → 4s, cap ~30s
500 Gateway or upstream failure Idempotent requests are safe to retry

Errors use the OpenAI envelope {"error":{"message","type","param","code"}}, with type set to new_api_error (gateway) or upstream_error (upstream). Each message ends with a request ID — include it in support tickets. The gateway does not retry for you.

Chat usage is billed per token in three tiers: input, output, and cache read. Cache reads are cheaper than regular input, and reasoning tokens are billed as output. MirAPI uses a prepaid USD balance with no subscription and no monthly fee, and the balance never expires. When the balance runs out, requests return 403; top up and the same key works again immediately.

  • Keep /v1 in base_url — LangChain appends /chat/completions to the base URL.
  • Use model names verbatim from GET /v1/models; the vendor/ prefix is for console browsing only and is not part of the API name.
  • 403 with a valid key usually means the model is not whitelisted or the balance is exhausted.
  • 429 has no Retry-After header — implement backoff yourself.