n4nAI

Migrating from OpenRouter to n4n: what changes in billing

A practitioner's step-by-step guide to migrate from OpenRouter to n4n billing changes: repoint endpoints, replace cost fields with per-token metering, verify.

n4n Team3 min read748 words

Audio narration

Coming soon — every post will get a voice note here.

When you migrate from OpenRouter to n4n billing changes, the first thing you’ll notice is that cost visibility shifts from an opaque credit deduction to explicit per-token metering. OpenRouter returns a cost field in USD on each completion; n4n.ai returns standard token counts and meters them downstream, which means your code must own the price math. This guide walks through the concrete steps to move your billing instrumentation without losing auditability.

Step 1: Audit your current OpenRouter cost tracking

Before you migrate from OpenRouter to n4n billing changes, catalog every place your system reads cost. Most teams pull the cost attribute from the REST response or the OpenAI-compatible client extension. A typical OpenRouter call looks like this:

import requests

resp = requests.post(
    "https://openrouter.ai/api/v1/chat/completions",
    headers={"Authorization": f"Bearer {OR_KEY}"},
    json={"model": "openai/gpt-4o", "messages": [{"role": "user", "content": "hi"}]}
).json()

print(resp["usage"])  # {"prompt_tokens": 5, "completion_tokens": 10, "total_tokens": 15}
print(resp["cost"])    # 0.000135 (USD, OpenRouter-specific)

If you persist cost to your ledger, flag those lines. OpenRouter also exposes generation logs via its dashboard and /api/v1/generation endpoint, which some use for monthly reconciliation. Note which models you call and whether you rely on OpenRouter’s automatic provider fallback—because that affects which model string appears in billing.

Step 2: Repoint the client to the n4n endpoint

n4n.ai provides one OpenAI-compatible endpoint that addresses 240+ models. Swap the base URL and key; the request shape stays identical.

from openai import OpenAI

client = OpenAI(
    base_url="https://api.n4n.ai/v1",  # n4n OpenAI-compatible endpoint
    api_key="sk-n4n-..."
)

resp = client.chat.completions.create(
    model="openai/gpt-4o",
    messages=[{"role": "user", "content": "hi"}]
)

No changes to message format, temperature, or tool calls are required. If you previously set HTTP-Referer or X-Title for OpenRouter rankings, drop them—n4n ignores them. The response object is the standard OpenAI Completion with a usage field and no cost key.

Step 3: Replace cost fields with token metering

The core of the migrate from OpenRouter to n4n billing changes process is replacing the cost read with local price math. n4n meters per token; you multiply token counts by your negotiated or public rates. Keep a price table keyed by the exact model string returned, not the one requested—automatic fallback may serve a sibling model.

PRICES = {
    "openai/gpt-4o": {"prompt": 5e-6, "completion": 15e-6},
    "anthropic/claude-3.5-sonnet": {"prompt": 3e-6, "completion": 15e-6},
}

def record_usage(model, usage):
    # usage is resp.usage from the n4n response
    price = PRICES.get(model)
    if not price:
        raise ValueError(f"no price for {model}")
    cost = usage.prompt_tokens * price["prompt"] + usage.completion_tokens * price["completion"]
    ledger.append({"model": model, "tokens": usage.total_tokens, "cost": cost})

Cache hits complicate this. Providers like Anthropic bill cached input tokens at a discount. n4n forwards provider cache-control hints, so if you send cache_control in the request, the usage object may include prompt_tokens_details.cached_tokens. Extend your price table to handle that tier:

if usage.prompt_tokens_details and usage.prompt_tokens_details.cached_tokens:
    cached = usage.prompt_tokens_details.cached_tokens
    uncached = usage.prompt_tokens - cached
    cost = cached * price["cached_prompt"] + uncached * price["prompt"] + ...

Step 4: Preserve routing and cache directives

OpenRouter accepts a route parameter and proprietary cache hints. When you migrate from OpenRouter to n4n billing changes, move those to provider-native shapes. n4n honors client routing directives and forwards cache-control hints without translation. For Anthropic models, embed the hint in the message:

messages=[
    {"role": "user", "content": [
        {"type": "text", "text": "System context", "cache_control": {"type": "ephemeral"}}
    ]}
]

If you relied on OpenRouter to fall back across providers on 429s, note that n4n performs automatic fallback when a provider is rate-limited or degraded. Your ledger must therefore record resp.model (the actual served model), not the requested one, or your per-token sums will mismatch the metering API.

Step 5: Capture metering for reconciliation

After you migrate from OpenRouter to n4n billing changes, treat n4n’s per-token usage metering as the source of truth. While the response gives you immediate tokens, aggregate counts are available via your dashboard and programmatic usage endpoints. Instrument your client to emit structured logs on every call:

import logging

logging.info("llm_usage", extra={
    "model": resp.model,
    "prompt_tokens": resp.usage.prompt_tokens,
    "completion_tokens": resp.usage.completion_tokens,
    "request_id": resp.id
})

If you need to attribute cost to internal teams, pass a stable user field or custom header (check n4n docs for the exact tagging header) so the metering breaks down by tag. Do not compute cumulative spend from your own logs alone—treat them as a shadow ledger and reconcile against n4n’s metering nightly.

# Example reconciliation diff (pseudo)
curl -s https://api.n4n.ai/v1/usage?day=2025-03-01 \
  -H "Authorization: Bearer $N4N_KEY" > n4n_usage.json
python diff_ledger.py local_ledger.json n4n_usage.json

Step 6: Verify the migration end to end

After you migrate from OpenRouter to n4n billing changes, run a controlled test. Pick a fixed prompt, send it to both old and new endpoints (or replay from logs), and assert:

  1. n4n response has usage.total_tokens > 0 and no cost key.
  2. The returned model matches expectation or a documented fallback sibling.
  3. Your local price math produces a nonzero cost within 1% of the same call on OpenRouter (using public rates).
  4. The call appears in n4n metering within the hour.

A minimal verification script:

def verify():
    r = client.chat.completions.create(
        model="openai/gpt-4o",
        messages=[{"role": "user", "content": "Say 'ok'."}]
    )
    assert not hasattr(r, "cost"), "n4n should not return cost"
    assert r.usage.total_tokens > 0
    assert r.model.startswith("openai/") or r.model in FALLBACK_ALLOWED
    print("OK", r.usage.model_dump())
verify()

If all four hold, cut over production traffic. Keep the OpenRouter key active for a week to diff aggregate spend; the per-token metering on n4n should sum to the same magnitude as OpenRouter’s cost totals after you apply identical price rates.

Common pitfalls

  • Assuming model is constant. Fallback changes it; bill by resp.model.
  • Ignoring cached token tiers. Forward cache hints and price them correctly or you overstate cost.
  • Polling too aggressively. n4n metering is eventual; reconcile on a daily cadence, not per request.
  • Hardcoding cost in analytics. Search your codebase for .cost and resp["cost"] before flip.

The migrate from OpenRouter to n4n billing changes is fundamentally a shift from consumed-credit abstraction to first-class token accountability. Do the ledger work up front and your finance team will trust the numbers.

Tagsbillingmigrationopenrouter

Written by

n4n Team

The team building n4n — a single OpenAI-compatible API in front of 240+ models, with automatic fallback, load balancing and pay-per-token metering.

More from n4n Team →

All migrating from openrouter to n4n posts →