Developer Documentation

Build with the Memcode Router.

A focused OpenAI-compatible gateway for text generation with per-key budgets, usage tracking, and rate limiting. Use the official OpenAI SDK and change only its API key and base URL.

Base URLhttps://api.memcode.in/v1

Quickstart

Ask your Memcode administrator for a router key. It starts withsm-openai-, sm-gemini-, or sm-anthropic-, followed by 32 lowercase hexadecimal characters, and is shown only once when it is created. The provider in the prefix determines which models the key can call. Keep it in an environment variable on your server. Never ship it in frontend JavaScript.

01

Install the SDK

npm install openai
02

Set your key

MEMCODE_API_KEY
03

Set the base URL

https://api.memcode.in/v1

JavaScript / TypeScript

server.mjs
import OpenAI from "openai";

const client = new OpenAI({
  apiKey: process.env.MEMCODE_API_KEY,
  baseURL: "https://api.memcode.in/v1",
});

const response = await client.responses.create({
  model: "gpt-5.6-terra",
  input: "Explain vector databases in one paragraph.",
  max_output_tokens: 256,
});

console.log(response.output_text);

Python

app.py
import os
from openai import OpenAI

client = OpenAI(
    api_key=os.environ["MEMCODE_API_KEY"],
    base_url="https://api.memcode.in/v1",
)

response = client.responses.create(
    model="gpt-5.6-terra",
    input="Explain vector databases in one paragraph.",
    max_output_tokens=256,
)

print(response.output_text)

cURL

terminal
curl https://api.memcode.in/v1/responses \
  -H "Authorization: Bearer $MEMCODE_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "gpt-5.6-terra",
    "input": "Explain vector databases in one paragraph.",
    "max_output_tokens": 256
  }'

Always choose a small explicit output cap. If you omit it, the router reserves budget for 4,096 output tokens before sending the request upstream.

Authentication

Send the router key as a Bearer token on every API request. The key identifies its owner, budget, status, and rate-limit bucket.

HTTP header
Authorization: Bearer $MEMCODE_API_KEY
  • Keys are case-sensitive and cannot be recovered later.
  • Do not put a key in a URL, query string, browser bundle, or log.
  • Revoked keys cannot generate, but can still read their final balance.
  • Do not use the upstream OpenAI key; use only your Memcode router key.

Endpoints

The router intentionally implements a small, documented subset of the OpenAI API. It is not a transparent proxy for every OpenAI feature.

MethodRoutePurpose
/v1/responsesGenerate text with the Responses API.
/v1/chat/completionsGenerate text with Chat Completions.
/v1/modelsList the router's accepted model IDs.
/user/balanceRead budget, usage, reservations, and key status.

The Responses API is OpenAI-only: Gemini and Anthropic keys can use POST /v1/chat/completions only. Unknown routes and wrong methods return a structured404 unknown_endpoint response.

Responses API

Use POST /v1/responses for new integrations. The router accepts string input or a non-empty array of text messages, Codex agent messages, encrypted reasoning history, and client tool call/output items.

JavaScript
import OpenAI from "openai";

const client = new OpenAI({
  apiKey: process.env.MEMCODE_API_KEY,
  baseURL: "https://api.memcode.in/v1",
});

const response = await client.responses.create({
  model: "gpt-5.6-terra",
  input: "Explain vector databases in one paragraph.",
  max_output_tokens: 256,
});

console.log(response.output_text);

model

One exact ID from the model table below.

input

Text or supported text/function items.

instructions

Optional string instructions.

max_output_tokens

Integer from 1 to 16,384.

stream

Optional boolean.

tools

Client-defined function and custom tools.

history

Stateless only: the router forces store=false and encrypted reasoning replay.

Chat Completions

Existing text-only Chat Completions clients can usePOST /v1/chat/completions. Messages must be non-empty and text-only.

JavaScript
const completion = await client.chat.completions.create({
  model: "gpt-5.6-luna",
  messages: [
    { role: "system", content: "Be concise." },
    { role: "user", content: "What is retrieval-augmented generation?" },
  ],
  max_completion_tokens: 256,
});

console.log(completion.choices[0].message.content);
  • Use max_completion_tokens from 1 to 16,384.
  • Legacy max_tokens is normalized unless it conflicts with max_completion_tokens.
  • n may be 1 to 8. Budget reservation scales with output cap × n.
  • Function tools are supported; hosted provider tools are not.

Streaming

Set stream: true. The router forwards OpenAI's SSE stream while inspecting the final usage event so it can settle the reservation.

JavaScript
const stream = await client.responses.create({
  model: "gpt-5.6-terra",
  input: "Count from one to five.",
  max_output_tokens: 64,
  stream: true,
});

for await (const event of stream) {
  if (event.type === "response.output_text.delta") {
    process.stdout.write(event.delta);
  }
}

Settlement happens after the stream completes. The reserved balance can remain visible briefly. If the client disconnects, the stream fails, or usage is missing, the router conservatively charges the full reservation.

Models and ledger pricing

Only the exact IDs below are accepted. The selected ID is forwarded unchanged, with no rewrites or silent fallbacks. A key's provider — visible in its sm-<provider>- prefix — determines which models it can call, and Gemini and Anthropic models are available on /v1/chat/completions only.

Model IDsInput / 1MCached / 1MOutput / 1M
gpt-5.6-terra$2.00$0.20$12.00
gpt-5.6-luna$0.20$0.02$1.20
gpt-5-mini, gpt-5-mini-2025-08-07$0.25$0.025$2.00
gpt-4.1-mini, gpt-4.1-mini-2025-04-14$0.40$0.10$1.60
gemini-3.1-pro-preview$2.00$0.20$12.00
gemini-3.7-flash$0.75$0.075$3.75
gemini-3.1-flash-lite$0.25$0.025$1.50
claude-sonnet-4-6$3.00$0.30$15.00
claude-opus-4-8$5.00$0.50$25.00

These are router-configured ledger rates, not a guarantee of the final provider invoice. Pricing can change, and calls made directly to a provider are outside this router's budget. GPT-5.6 cache writes cost 1.25 times uncached input; requests above 272,000 input tokens cost 2 times the input rate and 1.5 times the output rate for the full request. On gemini-3.1-pro-preview, requests above 200,000 input tokens bill 2 times the input rate and 1.5 times the output rate.

Check a key balance

Use the dashboard's Check Balance page or call the endpoint directly. This request does not call OpenAI or reserve budget, but it does consume request rate-limit capacity.

terminal
curl https://api.memcode.in/user/balance \
  -H "Authorization: Bearer $MEMCODE_API_KEY"
response
{
  "budgetLimit": 10,
  "balanceUsed": 1.25,
  "balanceReserved": 0.05,
  "remaining": 8.7,
  "isActive": true
}

How budgets work

Before contacting OpenAI, the router estimates a conservative maximum cost and atomically reserves it in PostgreSQL. A request is admitted only while:

invariant
balance_used + balance_reserved ≤ budget_limit
  1. The output cap, number of choices, body size, and configured rates determine the reservation.
  2. Concurrent requests reserve under a row lock, so they cannot collectively pass the key budget.
  3. Valid token usage settles the actual charge and releases the unused portion.
  4. Missing usage, ambiguous upstream delivery, timeout, or stream interruption charges the full reservation.

This is a hard router-ledger limit, not a guarantee about the upstream invoice. Direct OpenAI calls, stale pricing, and costs outside this gateway are not included.

Compatibility and limits

Request body

Valid UTF-8 JSON, currently up to 1 MiB.

Output

Default 4,096; explicit maximum 16,384 tokens.

Content

Text and client-defined tools; custom tools are Responses-only.

Service tier

Absent or default; the router forces default.

Queries

Generation queries are rejected; /v1/models ignores discovery query metadata locally.

Timeout

Current upstream timeout is 120 seconds.

Not supported

  • Images, audio, files, and non-text modalities.
  • Built-in/provider tools, web search, or web_search_options.
  • Background responses, hosted prompts, or conversations.
  • previous_response_id, prediction, or non-default service tiers.
  • x-goog-* headers and browser calls from any Origin other than https://router.memcode.in. Server-side calls without an Origin header are accepted.

Fields outside this documented subset are not a compatibility promise. OpenAI may accept or reject forwarded fields.

Rate limits

Requests pass through pre-authentication and authenticated token buckets. Limits are configurable, so clients should react to response headers instead of hard-coding current values.

Per key

Burst 20; refill 5 every 10 seconds.

Global traffic

Burst 200; refill 50 every 10 seconds.

Per presented key before auth

Burst 60; refill 20 every 10 seconds.

Global auth attempts

Burst 500; refill 100 every 10 seconds.

Useful headers

  • x-ratelimit-remaining-requests
  • x-ratelimit-remaining-global-requests
  • x-ratelimit-reset-requests-ms
  • retry-after on retryable limiter responses
  • x-router-request-id on every response

Errors

Errors use an OpenAI-style envelope with a stable router code.

JSON
{
  "error": {
    "message": "The requested model is not supported or priced by this gateway.",
    "type": "invalid_request_error",
    "param": "model",
    "code": "unsupported_model"
  }
}
Status / codeMeaningAction
400 invalid_requestFix the malformed or unsupported request field.Follow the message and code; retry only when appropriate.
400 unsupported_modelUse one of the exact model IDs listed above.Follow the message and code; retry only when appropriate.
401 invalid_api_keyCheck the key or ask the administrator for a new one.Follow the message and code; retry only when appropriate.
403 key_inactiveThe key was revoked or deactivated; do not retry generation.Follow the message and code; retry only when appropriate.
413 request_too_largeReduce the JSON body below the configured limit.Follow the message and code; retry only when appropriate.
415 unsupported_media_typeSend Content-Type: application/json.Follow the message and code; retry only when appropriate.
429 budget_exceededReduce the output cap or ask for a larger budget.Follow the message and code; retry only when appropriate.
429 rate_limit_exceededHonor Retry-After and retry with exponential backoff.Follow the message and code; retry only when appropriate.
502 upstream_errorRetry carefully; delivery can be ambiguous and budget may settle.Follow the message and code; retry only when appropriate.
503 budget_unavailableThe budget ledger is unavailable; retry later.Follow the message and code; retry only when appropriate.
504 upstream_timeoutThe upstream timed out; inspect the request ID before retrying.Follow the message and code; retry only when appropriate.

Include x-router-request-id when asking the operator for help. Upstream error bodies are sanitized and are not passed through verbatim.

Security and reliability

  • Keep router keys only in server-side secrets.
  • Set a small explicit output-token cap.
  • Use HTTPS and never disable TLS verification.
  • Honor 429 Retry-After and use bounded backoff.
  • Log x-router-request-id, never the API key.
  • Check balance before large or parallel jobs.
  • Do not assume retries are idempotent.
  • Rotate a key immediately if it is exposed.

For SDK installation and general OpenAI API concepts, see the official OpenAI quickstart. Memcode's supported subset and budget rules on this page take precedence for this gateway.

Need access or a budget change? Contact your Memcode administrator. Return to the integration guide.