A Moonshot API relay is essentially an extra layer between your application and the official open platform. It can bring a unified entry point, RMB billing, multi-model switching and failover—but it can also bring model substitution, unclear billing rules, key leakage and an additional point of failure. In 2026, Moonshot replaced its mainline models with the Kimi K3 and K2.7 series and retired moonshot-v1. If a relay does not update its model table in time, you get the hidden problem of "the API works, but the results are wrong."

This article does not recommend a specific provider. It explains how to evaluate one, how to reconcile its bills, and how to migrate. Models and prices follow the model pricing page.

Note: Moonshot, Kimi and Moonshot AI are trademarks or registered trademarks of Beijing Moonshot Technology Co., Ltd. This article is for technical discussion only and has no affiliation with the rights holder. The qualifications, terms and billing rules of each relay service are provided by that provider; verify them yourself before signing.

1. First, distinguish four kinds of relay

The word "relay" is used loosely. There are at least four types, and their boundaries of responsibility are completely different:

  • Managed gateway: The provider maintains a unified entry point and offers sub-keys, usage statistics, model routing and invoicing. You are buying technical service plus quota.
  • Resale or distribution: The provider resells quota from its own upstream account, possibly priced by a multiplier or a plan. Who owns the upstream account and what tier it is on directly affect stability.
  • Self-hosted gateway: You deploy software such as one-api or new-api, and the upstream keys remain yours. You have the most control, but operations, upgrades and disaster recovery are all your responsibility.
  • Cloud marketplace or aggregation platform: You activate the service inside a cloud vendor or aggregation platform, and billing follows the platform. The model range may be broader, but you still need to confirm the upstream and data terms.

First establish whether you are buying "technical service" or "model quota," then discuss price. The responsible party differs when each one fails.

2. Keys and model mapping: the most easily overlooked risk

A relay can see the full request and response on the link. That is a property of the architecture, not a question of trust. For requests containing personal information, contracts or internal code, confirm whether data is persisted, how long it is retained, and whether it is used for training. Mask sensitive data or use a direct connection where necessary.

More hidden than data is model mapping. Common risks include:

  • An old model name is silently mapped to a cheaper or shorter model; the API does not return an error, but quality drops.
  • At peak times, requests are downgraded to a lower-capacity channel while the model field in the response stays the same.
  • Keys from the China and international sites are mixed; everything works normally until a regional check suddenly returns 401.
  • Multiple customers share the same upstream account, and when someone else saturates concurrency, your requests start returning 429.
  • The upstream account triggers risk-control throttling due to unusual behavior, and that restriction may not be removable.

The contract should therefore specify the model mapping table, degradation rules and notification mechanism. At minimum, require the relay to preserve the real model, usage and request_id in responses, and allow you to export request logs.

3. Billing transparency: turn the rules into a reconciliation table

Moonshot's current mainline K3 bills separately for input cache hits, cache misses, cache writes and output, and cache writes are further divided by TTL. If a relay reports only one "total token count," you cannot tell whether caching actually worked, and you cannot verify the multiplier.

Reconciliation item What to check Common discrepancy
Cache writes Billed separately? What is the TTL? Cache writes counted as ordinary input
Cache-hit input Is the hit portion charged at the discounted rate? Everything charged at the miss rate
Cache-miss input Does it match the official rules? Inflated input token counts
Output tokens Do they include reasoning content? Reasoning-token rules unclear
Retried requests Are they billed twice? A timeout retry charged as two requests
Failed requests How are 429, 5xx and disconnects handled? Charges applied even on failure
Search and batch Priced separately? Mixed into the chat bill

Before signing, clarify four things: whether the billing unit is tokens, a plan or a multiplier; whether there is a minimum spend and how price changes are announced; whether failures and retries are billed; and who issues the invoice and under what category. If the price is clearly below the official one, ask whether the source is bulk purchasing, a subsidy or shared quota. Do not look only at the number.

4. Latency and errors: monitor these metrics

A single speed test is meaningless; observe continuously for at least a week. Fix a set of requests and record separately:

  • TTFT: Time to first token. In streaming scenarios it reflects the user experience better than total duration.
  • p50 / p95 latency: Look at the tail, not the average.
  • Error rate: Break it down by 401, 403, 404, 429, 499, 5xx and error.type.
  • Model dimension: Compare the same request across models and channels separately.
  • Usage consistency: Check whether usage in the response matches the bill.

Below is a minimal probe script, used only to verify the link and record metrics:

import os, time
from openai import OpenAI

client = OpenAI(
    api_key=os.environ["RELAY_KEY"],
    base_url=os.environ["RELAY_BASE"],
    max_retries=0,
)

start = time.time()
try:
    resp = client.chat.completions.create(
        model=os.environ["MODEL"],
        messages=[{"role": "user", "content": "Reply with OK only"}],
        max_completion_tokens=16,
    )
    elapsed = time.time() - start
    print({
        "ok": True,
        "latency_ms": round(elapsed * 1000),
        "model": resp.model,
        "usage": resp.usage.model_dump() if resp.usage else None,
        "request_id": resp.id,
    })
except Exception as exc:
    print({"ok": False, "latency_ms": round((time.time() - start) * 1000),
           "error": type(exc).__name__, "detail": str(exc)[:200]})

In production, write the results into a time-series database and aggregate p50, p95, error rate and model distribution by hour. Alerting only on "failure" without distinguishing specific types of 429 still leaves the on-call engineer unable to decide whether to slow down, top up or switch.

5. Migration checklist: moving from direct connection to a relay

  1. Inventory existing model names and confirm whether the retired moonshot-v1 is still in use; migrate to kimi-k3, kimi-k2.7 or kimi-k2.6 first.
  2. Fix a set of regression requests covering short Q&A, long documents, streaming, tool calling and image input.
  3. Send the same requests to both the direct connection and the relay, and compare model, usage, request_id and output quality.
  4. Verify every API format the project actually uses: Chat Completions, Responses or Anthropic Messages. Do not test only one.
  5. Check that streaming returns chunk by chunk and ends completely, and that an intermediate proxy has not disabled buffering.
  6. Deliberately trigger 401, 404 and 429, and confirm that error types and messages are readable and mapped correctly by the client.
  7. Reconcile the real bill against usage, covering cache, retries and failed requests.
  8. Roll out to low-risk traffic first, keep a switch to roll back to direct connection, and observe for at least a week before moving core traffic.

Migration is not just changing the Base URL and key. Model names, parameters, error types, usage statistics and invoicing paths are all the places most likely to break after the switch.

6. How to verify a relay

Verification should combine multiple signals; a single metric cannot prove origin:

  • Does the model in the response match the request, and are there any undeclared downgrades?
  • Is the usage structure complete, and do the cache fields match the official rules?
  • Is request_id traceable, and can it be matched against the relay's logs?
  • Compare outputs with a fixed evaluation set against the direct connection, checking that quality and latency are stable.
  • Are all three API formats supported, and are parameter extensions passed in the official way?
  • Do error responses preserve error.type, rather than wrapping everything as a generic "service error"?
  • Do the invoicing entity, contracting entity and payee entity match?
  • Is there a status page, an SLA, incident notifications and a history of availability?

If the relay cannot provide this information, it is not suitable for core business. The trial period should cover at least one full billing cycle, so you do not see normal service at the start of the month and throttling at the end.

7. Design the exit mechanism in advance

The biggest hidden cost of a relay layer is lock-in. Before signing, confirm: can keys be revoked at any time, can sub-keys be isolated by project, can logs be exported, can unused balance be refunded, how soon is data deleted, and how much notice is given before a price change? Only when migration cost is low do you have room to negotiate.

Self-hosted gateways have an exit problem too: the software version, plugins, database and upstream keys are in your hands, but if no one maintains them, upgrades and security patches fall behind. Choosing self-hosting means accepting that long-term staffing cost.

FAQ

Is a relay always more stable than a direct official connection?

Not necessarily. A relay can add retries, queuing and failover, but it also adds a failure point. Stability depends on the provider's operations capability, the quality of the upstream account and your timeout configuration. Validate it with at least a week of real traffic.

Is a relay price below the official price normal?

It may come from bulk purchasing, subsidies or shared quota, or it may come from creative billing rules. Ask about the billing unit, cache rules and whether failed requests are charged, then verify against the bill.

Can a self-built proxy solve 429 errors?

It cannot create upstream quota out of thin air. A proxy can only queue, slow down, retry and switch; if the upstream account's concurrency or TPD is exhausted, you still have to wait for a reset or raise the tier.

How can I tell whether a relay is really using Moonshot?

Check model, usage and request_id in the response, then compare against the direct connection with a fixed evaluation set. Combined verification is more reliable than any single metric; when in doubt about the origin, prefer a direct connection.

How much code has to change to move to a relay?

For OpenAI-compatible projects, usually only the Base URL, key and model name. However, streaming, timeouts, error-type mapping and usage statistics must be retested; these are the areas most likely to break after a switch.

Next steps

Create a test key on the ZSQH AI Gateway, run through the probe script and migration checklist in this article, and then decide which workloads should use a direct connection and which should use the gateway. Specific models, billing rules and availability follow the model pricing page.

Related reading: