US

using-openrouter

Helper for calling OpenRouter models with strict JSON enforcement, cost accounting, and model pinning.

Install

mkdir -p .claude/skills/using-openrouter && curl -L -o skill.zip "https://agentskills.codes/api/skills/download/19062" && unzip -o skill.zip -d .claude/skills/using-openrouter && rm skill.zip

Installs to .claude/skills/using-openrouter

Activation

This is the description your AI agent reads to decide when to run this skill — the better it matches your request, the more reliably it fires.

How to call OpenRouter correctly from this CV app (Python, OpenAI SDK) — strict JSON-schema generation, provider pinning, reasoning control, cost accounting, and the verified model slugs. Use this skill WHENEVER you call OpenRouter here: generating CVs, judging JD coverage, or clustering jobs via qwen3-235b, qwen3.7-max, deepseek-v4-pro, or gpt-5.1; whenever you need guaranteed strict JSON, temperature-0 determinism, reasoning/thinking control, or per-call cost on OpenRouter; and for the model-migration / A-B work. Trigger even if the user just says "use OpenRouter", "call qwen/deepseek", "route via openrouter", or mentions OPENROUTER_API_KEY — don't hand-roll the request, use the helper here.
702 charsno explicit “when” triggerlonger than Claude Code's old 250-char listing cap (fine on current versions)
Intermediate

Key capabilities

  • Generate strict JSON responses from OpenRouter models
  • Control model provider routing for specific parameters
  • Manage cost accounting for OpenRouter API calls
  • Disable reasoning for JSON generation calls
  • Repair malformed JSON syntax in responses
  • Handle model-specific quirks like temperature rejection

How it works

The skill uses a helper script to call OpenRouter via the OpenAI SDK, enforcing parameter pinning, disabling reasoning, and enabling response healing for JSON output.

Inputs & outputs

You give it
client, model slug, messages, schema, schema name
You get back
JSON response and metadata including cost

When to use using-openrouter

  • Generating JSON responses
  • Switching between AI models
  • Tracking API usage costs

About this skill

Using OpenRouter (for this CV app)

OpenRouter gives one prepaid balance + one OpenAI-compatible key for ~every model. You call it with the official openai SDK by swapping base_url. The whole reason this skill exists is that one default behavior will silently break us, plus a few model-specific quirks. Internalize the four rules below and use the bundled helper.

scripts/or_client.py encodes all of this — import it, don't re-derive it. references/openrouter-reference.md has the exhaustive, sourced facts + per-provider tables. Read it when a detail here isn't enough or when slugs/providers need re-verifying.

The four rules that matter

  1. Always pin require_parameters for any JSON call. By default OpenRouter may route your request to a provider that doesn't support response_format and will silently ignore your schema — you get HTTP 200 with free-form prose, no error. The fix is extra_body={"provider": {"require_parameters": True}}, which routes only to providers that honor every parameter you sent. This is non-negotiable for deepseek-v4-pro (its cheapest/default endpoint, DeepSeek's own, does not enforce strict schema).

  2. gpt-5.1 rejects a custom temperature. Same quirk as on OpenAI direct (the GPT-5 family). Send temperature only to Qwen/DeepSeek; for gpt-5.1 rely on schema + seed.

  3. Turn reasoning OFF for JSON/judging calls. qwen3.7-max and deepseek-v4-pro are reasoning-capable. Thinking tokens are billed as output, add latency/nondeterminism, and some providers drop or leak them under json_schema. Send extra_body={"reasoning": {"enabled": False, "exclude": True}}. qwen3-235b-a22b-2507 is the non-thinking Instruct variant — cleanest for deterministic temp-0 judging.

  4. Non-streaming + Response Healing for reliability. Use stream=False so OpenRouter's free plugins:[{"id":"response-healing"}] can repair malformed JSON syntax (Qwen/DeepSeek emit invalid JSON a few % of the time; healing takes Qwen3-235B ~88% → ~99.98% valid). Healing fixes syntax, not schema adherence — always still validate the parsed dict and fail closed.

Verified model slugs (2026-06-17 — re-verify before long-term reliance)

PurposeSlugNotes
CV gen (incumbent / quality bar)openai/gpt-5.1native strict SO; no temperature; $1.25/$10
CV gen (cheap flagship)qwen/qwen3.7-max$1.25/$3.75; single provider (alibaba) = no failover; reasoning-capable
CV gen (cheapest flagship)deepseek/deepseek-v4-pro~$0.44/$0.87; native endpoint not strict — pinning mandatory
group + match (judge)qwen/qwen3-235b-a22b-2507~$0.09/$0.10; non-thinking; accepts temp=0 + seed

Slugs/providers drift. Confirm with strict_providers(slug) (in the helper) or GET /api/v1/models/{slug}/endpoints before trusting a provider list.

The canonical call (use the helper)

from scripts.or_client import or_client, chat_json, MODELS, STRICT_PROVIDERS

client = or_client()  # OpenAI SDK pointed at OpenRouter, key from .env

# Strict CV generation (reasoning off, provider pinned, healing on, cost returned):
cv, meta = chat_json(
    client, MODELS["deepseek-v4-pro"],
    messages=[{"role": "system", "content": system_prompt},
              {"role": "user", "content": jobs_xml}],
    schema=cv_schema, schema_name="tailored_cv",
    pin_providers=STRICT_PROVIDERS["deepseek/deepseek-v4-pro"],  # belt-and-suspenders
)
print(meta["served_by"], meta["cost_usd"])

# Deterministic temp-0 judge (non-thinking model, temp honored):
verdict, meta = chat_json(
    client, MODELS["qwen3-235b"],
    messages=judge_msgs, schema=judge_schema, schema_name="coverage",
    temperature=0, seed=7,
)

chat_json already: sets require_parameters, disables reasoning, enables healing, omits temperature for gpt-5.*, strips stray ```json fences, json.loads (raises on bad output — fail closed), and pulls cost/tokens from resp.model_dump()["usage"].

Strict-schema requirements (our build_cv_schema already complies)

Strict mode = every object has additionalProperties: false, every property is in required, optional fields are nullable unions ({"type": ["array", "null"]}), and constraint keywords (pattern, min/maxLength, format, default, …) are stripped/ignored. server/cv_schema.py:build_cv_schema already follows this exactly — reuse it, don't rewrite.

Cost, credits, errors (details in the reference)

  • Cost is auto-returned: resp.model_dump()["usage"]["cost"] (USD; the typed .usage.cost may be absent). Ground truth: GET /api/v1/generation?id=<id> (retry on 404 — written async).
  • Check balance before a batch: check_key() in the helper (GET /api/v1/key).
  • Retry 408/429/502/503/504; never retry 402 (no credits) or 403 (guardrail). require_parameters + too many filters → 503 (no eligible provider) — loosen a filter.

When to read the reference

references/openrouter-reference.md — per-provider strict-SO tables for each model, the full reasoning/billing model, prompt-caching specifics, privacy/data controls, the complete error table, and every source URL. Go there before changing provider pins or debugging a routing/ schema/temperature surprise.

When not to use it

  • When not calling OpenRouter
  • When not needing guaranteed strict JSON
  • When not needing per-call cost on OpenRouter

Prerequisites

OpenAI SDKOPENROUTER_API_KEY

Limitations

  • The `gpt-5.1` model rejects a custom `temperature` parameter.
  • Response healing fixes JSON syntax, not schema adherence.
  • Some providers may drop or leak thinking tokens under `json_schema`.

How it compares

This workflow prevents silent schema breakage and handles model-specific quirks, unlike a direct, unmanaged OpenRouter API call.

Compared to similar skills

using-openrouter side by side with the closest alternatives in the catalog.

SkillInstallsUpdatedSafetyDifficulty
using-openrouter (this skill)017dReviewIntermediate
openai-knowledge54moNo flagsIntermediate
openrouter-function-calling510dReviewIntermediate
openrouter-hello-world710dCautionBeginner

Try saying

Example prompts that trigger this skill in your AI assistant.

You might also like

openai-knowledge

openai

Use when working with the OpenAI API (Responses API) or OpenAI platform features (tools, streaming, Realtime API, auth, models, rate limits, MCP) and you need authoritative, up-to-date documentation (schemas, examples, limits, edge cases). Prefer the OpenAI Developer Documentation MCP server tools when available; otherwise guide the user to enable `openaiDeveloperDocs`.

539

openrouter-function-calling

jeremylongshore

Implement function/tool calling with OpenRouter models. Use when building agents or structured outputs. Trigger with phrases like 'openrouter functions', 'openrouter tools', 'openrouter agent', 'function calling'.

539

openrouter-hello-world

jeremylongshore

Create your first OpenRouter API request with a simple example. Use when learning OpenRouter or testing your setup. Trigger with phrases like 'openrouter hello world', 'openrouter first request', 'openrouter quickstart', 'test openrouter'.

733

openrouter-openai-compat

jeremylongshore

Configure OpenRouter as an OpenAI API drop-in replacement. Use when migrating from OpenAI or using OpenAI-compatible libraries. Trigger with phrases like 'openrouter openai', 'openrouter drop-in', 'openrouter compatibility', 'migrate to openrouter'.

13

gemini-openai-api

Project-N-E-K-O

Gemini 模型通过 OpenAI 兼容 API 接入指南。包含:(1) 辅助 API 配置(summary/correction/emotion/vision),(2) extra_body 格式用于控制 thinking,(3) 响应格式处理(markdown 代码块)。当需要将 Gemini 作为辅助模型接入、配置 thinking 参数、或处理 Gemini API 返回格式时使用。

01

fastapi-templates

wshobson

Create production-ready FastAPI projects with async patterns, dependency injection, and comprehensive error handling. Use when building new FastAPI applications or setting up backend API projects.

5201,086

Search skills

Search the agent skills registry