OpenAI API Gateway
Checking health…

OpenAI API Gateway

A transparent middleman proxy for https://api.openai.com. Your client keeps speaking the exact OpenAI protocol — you change only the base URL. Requests and responses pass through byte-for-byte, including streaming.

Base URL https://openai.mrdisc.ir:9999
✓ Streaming (SSE) ✓ No account — bring your own key ✓ Official SDK compatible ✓ Location privacy ✓ CORS enabled (browser OK)

Overview

This gateway sits between your application and the OpenAI API. It listens on https://openai.mrdisc.ir:9999 and forwards every request to https://api.openai.com over TLS.

  • Transparent pass-through. Method, path, query string, headers (including Authorization) and the request body are forwarded exactly as you send them. The upstream response is returned exactly as OpenAI produces it — status code, headers, body and SSE event stream.
  • No registration. You authenticate with your own OpenAI API key. The gateway stores no keys, no accounts and no message contents.
  • Location privacy. Because the outbound connection originates from the gateway server, OpenAI only ever sees the gateway's IP address. Caller-identity headers (forwarded-for, cookies, language, referer…) are removed before forwarding — see Location privacy.
  • Universal compatibility. Works unchanged with the official OpenAI SDKs (Python and Node.js), LangChain, LlamaIndex, community libraries, and plain curl — anything that can call api.openai.com.
  • Self-documenting. This page is served by the gateway itself at / and /docs.

Base URL

Replace OpenAI's API origin with the gateway origin. Keep everything else — the /v1 prefix, paths, query strings — exactly the same.

Direct OpenAI callSame call via gateway
https://api.openai.com/v1/chat/completionshttps://openai.mrdisc.ir:9999/v1/chat/completions
https://api.openai.com/v1/embeddingshttps://openai.mrdisc.ir:9999/v1/embeddings
https://api.openai.com/v1/modelshttps://openai.mrdisc.ir:9999/v1/models

SDK configuration

ClientSettingValue
Python SDK (openai v1+)base_urlhttps://openai.mrdisc.ir:9999/v1
Node.js SDK (openai)baseURLhttps://openai.mrdisc.ir:9999/v1
Environment variableOPENAI_BASE_URLhttps://openai.mrdisc.ir:9999/v1
Legacy Python SDKopenai.api_basehttps://openai.mrdisc.ir:9999/v1
The base URL includes the /v1 suffix — the same suffix you use with OpenAI's default endpoint. SDKs append the rest of the path automatically.

Quick start

1 · Get an OpenAI API key

Create a key at platform.openai.com/api-keys. The gateway does not issue keys — billing, quotas and rate limits all come from your own OpenAI account.

2 · Point your client at the gateway

shell — environment variables (works for most libraries)
export OPENAI_API_KEY="sk-..."               # your OpenAI key
export OPENAI_BASE_URL="https://openai.mrdisc.ir:9999/v1"      # the only change

3 · Make a request

shell — chat completion
curl https://openai.mrdisc.ir:9999/v1/chat/completions \
  -H "Authorization: Bearer $OPENAI_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
        "model": "gpt-4o-mini",
        "messages": [
          {"role": "system", "content": "You are a helpful assistant."},
          {"role": "user", "content": "Hello!"}
        ]
      }'

That's it. The JSON you get back is structurally identical to OpenAI's own response — same id, choices, usage, created fields, same error shapes.

Code examples

Chat completion

non-streaming
curl https://openai.mrdisc.ir:9999/v1/chat/completions \
  -H "Authorization: Bearer $OPENAI_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
        "model": "gpt-4o-mini",
        "messages": [{"role": "user", "content": "Hello!"}]
      }'

Streaming

SSE — note the -N flag (disable curl buffering)
curl -N https://openai.mrdisc.ir:9999/v1/chat/completions \
  -H "Authorization: Bearer $OPENAI_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
        "model": "gpt-4o-mini",
        "stream": true,
        "messages": [{"role": "user", "content": "Write a haiku about proxies."}]
      }'

List models your key can access

GET request
curl https://openai.mrdisc.ir:9999/v1/models \
  -H "Authorization: Bearer $OPENAI_API_KEY"

Chat completion

pip install openai
from openai import OpenAI

client = OpenAI(
    api_key="sk-...",                          # your OpenAI API key
    base_url="https://openai.mrdisc.ir:9999/v1",                 # <-- the ONLY change
)

resp = client.chat.completions.create(
    model="gpt-4o-mini",
    messages=[{"role": "user", "content": "Hello!"}],
)
print(resp.choices[0].message.content)

Streaming

events arrive live, exactly as from OpenAI
stream = client.chat.completions.create(
    model="gpt-4o-mini",
    messages=[{"role": "user", "content": "Count from 1 to 5."}],
    stream=True,                               # SSE relayed in real time
)
for event in stream:
    delta = event.choices[0].delta.content
    if delta:
        print(delta, end="", flush=True)

Embeddings

any SDK method works
emb = client.embeddings.create(
    model="text-embedding-3-small",
    input="The quick brown fox",
)
print(len(emb.data[0].embedding))

Chat completion

npm install openai
import OpenAI from "openai";

const client = new OpenAI({
  apiKey: "sk-...",                            // your OpenAI API key
  baseURL: "https://openai.mrdisc.ir:9999/v1",                   // <-- the ONLY change
});

const resp = await client.chat.completions.create({
  model: "gpt-4o-mini",
  messages: [{ role: "user", content: "Hello!" }],
});
console.log(resp.choices[0].message.content);

Streaming

async iterator
const stream = await client.chat.completions.create({
  model: "gpt-4o-mini",
  messages: [{ role: "user", content: "Count from 1 to 5." }],
  stream: true,
});
for await (const event of stream) {
  const delta = event.choices[0]?.delta?.content ?? "";
  process.stdout.write(delta);
}

Plain HTTP request

pip install requests
import requests

r = requests.post(
    "https://openai.mrdisc.ir:9999/v1/chat/completions",
    headers={"Authorization": "Bearer sk-..."},
    json={
        "model": "gpt-4o-mini",
        "messages": [{"role": "user", "content": "Hello!"}],
    },
    timeout=120,
)
r.raise_for_status()
print(r.json()["choices"][0]["message"]["content"])

Streaming with raw HTTP

parse the data: lines yourself
import json
import requests

with requests.post(
    "https://openai.mrdisc.ir:9999/v1/chat/completions",
    headers={"Authorization": "Bearer sk-..."},
    json={"model": "gpt-4o-mini", "stream": True,
          "messages": [{"role": "user", "content": "Hi"}]},
    stream=True, timeout=300,
) as r:
    for line in r.iter_lines():
        if not line or not line.startswith(b"data: "):
            continue
        payload = line[len(b"data: "):]
        if payload == b"[DONE]":
            break
        chunk = json.loads(payload)
        delta = chunk["choices"][0]["delta"].get("content", "")
        print(delta, end="", flush=True)

Supported endpoints

Every path is forwarded verbatim — if OpenAI serves it, it works through the gateway. The commonly used families:

FamilyPath(s)Notes
Chat CompletionsPOST /v1/chat/completionstools / function calling, vision inputs, JSON mode, logprobs, stream
Responses APIPOST /v1/responsesfully proxied; server-side state lives on OpenAI
Completions (legacy)POST /v1/completions
EmbeddingsPOST /v1/embeddings
ImagesPOST /v1/images/generations · /edits · /variationsbase64 or URL results, both pass through
Audio → textPOST /v1/audio/transcriptions · /translationsmultipart file uploads pass through (OpenAI caps uploads at 25 MB)
Text → speechPOST /v1/audio/speechbinary audio response streamed back
FilesGET/POST /v1/files · GET /v1/files/{id}/contentdownloads stream through the gateway
Fine-tuningGET/POST /v1/fine_tuning/jobs · /{id} · /{id}/cancel…
BatchPOST /v1/batches · GET /v1/batches/{id}…input/output files ride the Files API
ModelsGET /v1/models · GET /v1/models/{model}lists everything your key can access
ModerationsPOST /v1/moderations
Anything elseany pathforwarded verbatim — new OpenAI endpoints need no gateway update
Not supported: the Realtime API (/v1/realtime) — it requires WebSocket, and the gateway speaks HTTP + SSE only.

Streaming (SSE)

Set "stream": true in the request body, exactly as with OpenAI. The gateway relays server-sent events as they arrive — there is no buffering stage, so time-to-first-token and inter-chunk timing match the direct connection (plus one network hop).

  • Each SSE event is forwarded in its own TCP flush.
  • The terminal data: [DONE] marker passes through untouched.
  • Chunked transfer framing is re-encoded for your client, but the event payload bytes are identical.
  • If your client disconnects mid-stream, the upstream leg is cancelled immediately.

See the cURL / SDK tabs in Code examples for ready-to-run streaming snippets.

Authentication

The gateway is a pure middleman — it has no accounts and no keys of its own. You present your OpenAI key exactly as you would to OpenAI:

request header
Authorization: Bearer sk-...4A2c          # your OpenAI API key, passed through untouched
  • Optional OpenAI-Organization: org-... and OpenAI-Project: proj-... headers are forwarded as well.
  • A missing or invalid key produces OpenAI's own 401 response, verbatim — the gateway never rewrites or interprets credentials.
  • Keys are never logged, cached or stored anywhere on the gateway.

Passthrough fidelity

Passed through untouched

ElementGuarantee
HTTP methodidentical (GET, POST, PUT, PATCH, DELETE, HEAD)
Path + query stringidentical, byte-for-byte
Request bodyidentical bytes (JSON, multipart/form-data, binary)
Authorization + OpenAI-* headersidentical
Response status codeidentical (200, 401, 429, 500…)
Response headersidentical (content-type, x-request-id, openai-*, x-ratelimit-*…)
Response bodyidentical bytes — same JSON structure, same usage, same id values
SSE event streamidentical events, relayed live
Error responsesOpenAI's exact error JSON, verbatim

Transport-level adjustments (never alter the API payload)

AdjustmentWhy
Host header rewritten to api.openai.comrequired for TLS and HTTP/1.1 routing to the upstream
Hop-by-hop headers dropped (Connection, Keep-Alive…)mandated by RFC 7230 §6.1 for any proxy
Content-Length recomputedbookkeeping after body re-framing
Chunked transfer re-framing on streamed responseslets SSE and close-delimited bodies stream to any HTTP/1.1 client
Caller-identity headers strippedlocation privacy — see below
CORS headers added to responseslets browser apps call the gateway directly — see limits

Errors

From OpenAI (passed through verbatim)

All OpenAI-generated errors — invalid key, rate limits, context length, content filter, server errors — reach you byte-identical, with OpenAI's original status code and headers:

example — 401 from OpenAI via the gateway
HTTP/1.1 401 Unauthorized

{
  "error": {
    "message": "Incorrect API key provided: sk-dummy. You can find your API key at https://platform.openai.com/account/api-keys.",
    "type": "invalid_request_error",
    "param": null,
    "code": "invalid_api_key"
  }
}

From the gateway (only when the gateway itself fails)

The only errors the gateway generates are connectivity faults between the gateway and OpenAI. They use the same {"error": {...}} envelope so your error handling stays uniform:

example — gateway-generated 502
HTTP/1.1 502 Bad Gateway

{
  "error": {
    "message": "Upstream connection failed: ...",
    "type": "gateway_error",
    "param": null,
    "code": "upstream_unreachable"
  }
}

Codes you can see: upstream_unreachable (cannot reach api.openai.com) and internal_error (unexpected gateway fault). Anything else you receive came from OpenAI itself.

Location privacy

The gateway removes every header that could identify you — your network, region, browser or session — before forwarding the request. OpenAI sees a request coming from the gateway server's IP address and nothing more.

Stripped before forwarding

removed from every request
X-Forwarded-For        X-Real-IP              X-Forwarded-Host
X-Forwarded-Proto      X-Forwarded-Port       X-Forwarded-Server
X-Forwarded-Scheme     Forwarded              Via
True-Client-IP         Client-IP              X-Client-IP
X-Cluster-Client-IP    CF-Connecting-IP       CF-IPCountry
CF-Ray                 CF-Visitor             Fastly-Client-IP
X-Country-Code         X-Geo-Country          X-Geo-Lat / X-Geo-Lon
Accept-Language        Referer                Origin
Cookie
  • Authorization and request payloads are not touched — only identity/location signals are removed.
  • The gateway logs one line per request (IP, method, path, status, bytes, duration) for operations — never keys, never bodies.
Encryption note: the gateway↔OpenAI leg is always TLS. The you↔gateway leg is plain HTTP on this server (a raw IP cannot hold a certificate). Anyone on the path between you and the gateway can observe the traffic — use it from trusted networks, exactly as you would treat any plain-HTTP API endpoint.

Limits & notes

AspectValue / behavior
You → gateway protocolplain HTTP on port 9999 (no TLS on a raw IP) — trusted networks only
Gateway → OpenAI protocolalways HTTPS (TLS 1.2+)
Timeout600 s per socket operation — long generations and slow streams are fine
Request bodiesbuffered in memory before forwarding (OpenAI caps uploads at 25 MB anyway)
Streamingfull SSE pass-through, chunk-by-chunk, zero buffering
WebSocket / Realtime APInot supported — every REST + SSE endpoint works
Rate limitsyour own OpenAI account's — 429 responses pass through untouched
Concurrencythreaded server; upstream keep-alive connection pool of 16, scales beyond on demand
Loggingone line per request (IP, method, path, status, bytes, duration) — never keys or bodies
Latencyone extra network hop between you and OpenAI
CORSenabled — browser apps may call the gateway directly; OPTIONS preflight is answered by the gateway. Remember your API key would ship to the browser, so only do this from pages your users trust.

Health check

A local endpoint (not proxied) for uptime monitors:

shell
curl https://openai.mrdisc.ir:9999/healthz
response
{"status":"ok","upstream":"api.openai.com"}

This documentation page is served at / and /docs. Every other path is proxied to OpenAI.

FAQ

Do I need an account on the gateway?

No. The gateway holds no accounts. You use your own OpenAI API key, and OpenAI's billing, quotas and rate limits apply exactly as if you called them directly.

Does the gateway store my API key or conversations?

No. Keys and request/response bodies are never written to disk or memory beyond the lifetime of the request. The only persistent log is a single metadata line per request (IP, method, path, status, bytes, duration).

Which SDKs and libraries work?

Any client that speaks the OpenAI REST protocol: the official Python and Node.js SDKs, LangChain, LlamaIndex, AutoGen, community libraries, and plain HTTP clients. All you change is the base URL / OPENAI_BASE_URL.

Which models can I use?

Every model your key can access — GET /v1/models lists them. The gateway adds no model filtering or mapping.

Why am I getting a 401?

The gateway does not touch your credentials, so a 401 comes from OpenAI itself. Check that you send Authorization: Bearer <your key> and that the key is valid and has credit.

Is streaming supported?

Yes — SSE is relayed chunk-by-chunk with no buffering. The [DONE] marker and every delta event arrive in real time.

Can I call it from a browser (fetch/JS)?

Yes — CORS is enabled (Access-Control-Allow-Origin: *) and preflight OPTIONS requests are answered by the gateway. Be aware the OpenAI key would be visible in the browser, so only do this for trusted frontends.

Does it work with Azure OpenAI or other providers?

No. This gateway proxies api.openai.com only.

Is the Realtime API available?

Not yet — it needs WebSocket, while the gateway speaks HTTP and SSE only. Every other endpoint works.

What does OpenAI see about me?

Only the gateway server's IP address, the request you sent (minus identity headers), and your API key. Your own IP, region, language, cookies and referrer are stripped.