Documentation

MrVinci OpenAI API

OpenAI-compatible proxy API. Everything below is a drop-in for the OpenAI Chat Completions API.

Surfaces

One host, landing and API together

The marketing pages you're reading and the API share this domain — the browser gets HTML at /, your client hits the API path below.

https://openai.mrvinci.app/v1/chat/completions
OpenAI chat · POST
https://openai.mrvinci.app/v1/responses
OpenAI Responses (Codex) · POST
https://openai.mrvinci.app/v1/models
Model list · GET
Prerequisites

What you need

Install

The one-minute path

The npx mrvinciapi wizard asks for your key, lets you pick your client, writes the config, and verifies the connection. Zero dependencies, pure Node — it only edits local files, never sends anything anywhere.

npx mrvinciapi --openai

Direct (no wizard)

# Claude Code
npx mrvinciapi sk_mv_YOUR_KEY
# Codex (OpenAI Responses)
npx mrvinciapi sk_mv_YOUR_KEY --codex
# Cursor / Cline
npx mrvinciapi sk_mv_YOUR_KEY --openai

Other flags

# print env, change nothing
npx mrvinciapi sk_mv_YOUR_KEY --print
# revert Claude Code
npx mrvinciapi --undo

Override hosts with MRVINCI_CLAUDE_BASE / MRVINCI_OPENAI_BASE for a self-hosted gateway.

Codex

Codex, via the Responses API

Codex defaults to wire_api = "responses". We serve a full OpenAI Responses endpoint at /v1/responses (streaming + non-streaming), so Codex works out of the box — npx mrvinciapi <key> --codex writes this for you.

Or add it to ~/.codex/config.toml and run codex --profile mrvinci:

[model_providers.mrvinci]
name = "MrVinci"
base_url = "https://openai.mrvinci.app/v1"
wire_api = "responses"
env_key = "MRVINCI_API_KEY"

[profiles.mrvinci]
model = "gpt-5.4"
model_provider = "mrvinci"

Export the key first: export MRVINCI_API_KEY="sk_mv_…".

Manual setup

Configure it yourself

Claude Code

Add to ~/.claude/settings.json:

{
  "env": {
    "OPENAI_API_KEY": "sk_mv_YOUR_KEY",
    "OPENAI_BASE_URL": "https://openai.mrvinci.app"
  }
}

Cursor / Cline

Base URL https://openai.mrvinci.app, API key sk_mv_…, model DeepSeek-V4-Pro.

API reference

POST /v1/chat/completions

curl https://openai.mrvinci.app/v1/chat/completions \
  -H "Authorization: Bearer sk_mv_YOUR_KEY" \
  -H "content-type: application/json" \
  -d '{
    "model": "DeepSeek-V4-Pro",
    "messages": [{"role":"user","content":"Hello"}]
  }'

Authenticate with x-api-key: sk_mv_… or Authorization: Bearer sk_mv_…. List models at /v1/models.

Image generation

POST /v1/images/generations

Send the OpenAI-compatible model, prompt, size, quality, and n fields. Image calls are billed per image, not per token.

curl https://openai.mrvinci.app/v1/images/generations \
  -H "Authorization: Bearer sk_mv_YOUR_KEY" \
  -H "content-type: application/json" \
  -d '{
    "model": "gpt-image-1-5",
    "prompt": "A brass astrolabe on a drafting table",
    "size": "1024x1024",
    "quality": "medium",
    "n": 1
  }'

Models: gpt-image-1-5, flux-2-pro. size and quality select the GPT Image price tier; FLUX is flat-rate. This generation endpoint does not accept reference images.

Capabilities

Tools, streaming, vision, image generation, caching

Everything the Chat Completions / Responses API supports works through the gateway — these aren't add-ons, they're the same wire format you already use.

Tool use (function calling)

Send a tools array exactly as the OpenAI SDK does — tool_use blocks stream back exactly as the API specifies. Agents like Claude Code, Cursor, and Cline run their whole tool loop through the gateway unmodified.

curl https://openai.mrvinci.app/v1/chat/completions \
  -H "Authorization: Bearer sk_mv_YOUR_KEY" \
  -H "content-type: application/json" \
  -d '{
    "model": "DeepSeek-V4-Pro",
    "tools": [{
      "type": "function",
      "function": {
        "name": "get_weather",
        "description": "Current weather for a city",
        "parameters": {"type":"object","properties":{"city":{"type":"string"}},"required":["city"]}
      }
    }],
    "messages": [{"role":"user","content":"Weather in Florence?"}]
  }'

Streaming

Set "stream": true for server-sent events with no added buffering — text deltas, tool calls arrive as they're generated.

Vision

Send images as image_url parts — exactly as the API specifies, streaming included.

Image generation

POST /v1/images/generations returns generated images in the OpenAI-compatible response shape and bills each image at its model tier.

Prompt caching

Cache reads are metered separately (cache_read_input_tokens in every response's usage) and billed at a fraction of the input price — keep your system prompt stable and long agent sessions get dramatically cheaper. No opt-in needed.

Responses API

POST /v1/responses serves the full OpenAI Responses wire format (streaming + non-streaming) — Codex and the Agents SDK work with zero config beyond the base URL.

Errors

Error reference

Errors come back in the OpenAI error envelope, so SDK retry logic behaves correctly. The rule: 429 and 529 are retryable (wait, then retry); 4xx everything else means fix the request.

StatusMeaningWhat to do
401Key missing, invalid, expired, or revoked — the message says which.Check the key on /usage; ask an admin to renew.
404Unknown model id.Pick an id from /v1/models.
413Request body over 32 MB (a very long unmanaged conversation).Don't retry the same body — compact or clear the conversation.
429Prepaid credit exhausted or per-minute limit reached.Honor retry-after or top the key up.
529The service is temporarily overloaded.Retry with backoff — official SDKs do this automatically.
Troubleshooting

When something's off

Changes not applied

Restart your IDE after editing its settings so it re-reads the base URL.

Is it us or you?

The status page live-checks every endpoint from your browser. If it's green and you're still stuck, it's the key or the request.

Key behaving oddly

Paste it on the usage page — revoked/expired state, limits, and per-model consumption are all visible, read-only.

Streaming stalls

Proxies and some serverless runtimes buffer SSE. Test with curl -N first; if that streams, the issue is between your app and us.