# How FreeLLMAPI Supports Zhipu AI Dual-Host Routing: Automatic Global vs Domestic Console Detection

> FreeLLMAPI automatically routes Zhipu AI requests to the correct host by detecting global or domestic console keys, ensuring seamless dual-host routing without manual setup.

- Repository: [Tashfeen/freellmapi](https://github.com/tashfeenahmed/freellmapi)
- Tags: deep-dive
- Published: 2026-08-27

---

**FreeLLMAPI automatically detects whether a Zhipu AI API key belongs to the domestic `bigmodel.cn` or global `z.ai` console by probing both endpoints during validation, then caches the result in memory to route all subsequent requests to the correct host without requiring manual configuration.**

FreeLLMAPI is an open-source LLM API gateway that normalizes access to multiple providers through a unified interface. When integrating with Zhipu AI—one of China's leading foundation model platforms—the system must handle the provider's unique dual-host architecture where domestic and global consoles operate on separate domains with distinct API key namespaces. According to the tashfeenahmed/freellmapi source code, the implementation in [`src/server/src/providers/zhipu.ts`](https://github.com/tashfeenahmed/freellmapi/blob/main/src/server/src/providers/zhipu.ts) handles this transparently through automatic host discovery and dynamic URL resolution.

## Understanding Zhipu AI's Dual-Host Architecture

Zhipu AI operates two separate console environments that require different base URLs:

- **Domestic Console**: Uses `https://open.bigmodel.cn/api/paas/v4` as the base endpoint. This is the original registration host for users within mainland China.
- **Global Console**: Uses `https://api.z.ai/api/paas/v4` as the base endpoint. This newer host serves international users and operates within a completely separate key namespace.

Because API keys are not interchangeable between these hosts— a key generated on the domestic console will return authentication errors on the global endpoint and vice versa—FreeLLMAPI must determine which host a given key belongs to before routing requests.

## The Dual-Host Routing Implementation in [`src/server/src/providers/zhipu.ts`](https://github.com/tashfeenahmed/freellmapi/blob/main/src/server/src/providers/zhipu.ts)

The `ZhipuProvider` class extends `OpenAICompatProvider` and encapsulates all dual-host logic through three core methods. The provider maintains an in-memory `globalKeys` Set that tracks which keys have been identified as belonging to the global console.

### Default Domestic Host Routing

By default, all Zhipu AI requests route to the domestic endpoint. The provider defines `DOMESTIC_BASE_URL` as the default base URL, ensuring backward compatibility for existing users who registered before the global console existed. Unless a key is explicitly identified as global, every chat completion, streaming request, and model catalog call targets `https://open.bigmodel.cn/api/paas/v4`.

### Automatic Host Detection via `validateKey()`

When `validateKey(apiKey: string)` is invoked, the provider initiates a validation probing sequence:

1. **Domestic probe first**: The provider queries the domestic `/models` endpoint using the provided key.
2. **Global fallback**: If the domestic request returns HTTP 401 or 403 authentication errors, the provider automatically probes the `GLOBAL_BASE_URL` endpoint.
3. **Key classification**: A successful response from the global endpoint marks the key as a global-console key and stores it in the in-memory `globalKeys` Set.

```typescript
// Simplified workflow from src/server/src/providers/zhipu.ts
async validateKey(apiKey: string): Promise<boolean> {
  // Probe domestic first
  const domesticOk = await this.probeDomestic(apiKey);
  if (domesticOk) return true;
  
  // If 401/403, try global
  const globalOk = await this.probeGlobal(apiKey);
  if (globalOk) {
    this.globalKeys.add(apiKey); // Cache as global key
    return true;
  }
  return false;
}

```

### Dynamic URL Rewriting with `resolveUrl()`

For every request, the `resolveUrl()` method checks if the provided API key exists in the `globalKeys` Set. If matched, it rewrites the request URL from the domestic base to the global base before delegating to the underlying fetch logic. The `fetchWithTimeout()` method overrides the base implementation to apply this resolution automatically.

```typescript
// Internal URL resolution logic
resolveUrl(url: string, init: RequestInit & { apiKey?: string }): string {
  if (init.apiKey && this.globalKeys.has(init.apiKey)) {
    return url.replace(DOMESTIC_BASE_URL, GLOBAL_BASE_URL);
  }
  return url;
}

```

This ensures that after initial validation, all chat completions, streaming responses, and model listing requests route to `https://api.z.ai/api/paas/v4` for global keys without requiring additional network probes.

## Practical Implementation Example

Instantiating and using the provider requires no host configuration—the system discovers the correct endpoint automatically:

```typescript
import { ZhipuProvider } from '@/server/src/providers/zhipu.js';

// Initialize with default domestic host
const zhipu = new ZhipuProvider({ timeoutMs: 60_000 });

// Validation automatically detects console type
await zhipu.validateKey('my-zhipu-api-key');

// Subsequent requests route to the correct host
const response = await zhipu.chatCompletion(
  'my-zhipu-api-key',
  [{ role: 'user', content: 'Explain quantum computing' }],
  'glm-4-flash'
);

```

If `my-zhipu-api-key` belongs to the global console, the provider internally rewrites the URL from `https://open.bigmodel.cn/api/paas/v4/chat/completions` to `https://api.z.ai/api/paas/v4/chat/completions` before executing the request.

## Key Files in the Routing Architecture

The dual-host implementation spans four critical files in the repository:

- **[`src/server/src/providers/zhipu.ts`](https://github.com/tashfeenahmed/freellmapi/blob/main/src/server/src/providers/zhipu.ts)**: Contains the `ZhipuProvider` class with `validateKey()`, `resolveUrl()`, and the `globalKeys` Set logic.
- **[`src/server/src/providers/openai-compat.ts`](https://github.com/tashfeenahmed/freellmapi/blob/main/src/server/src/providers/openai-compat.ts)**: Provides the `OpenAICompatProvider` base class that `ZhipuProvider` extends, handling standard OpenAI-compatible request formatting.
- **[`src/server/src/providers/index.ts`](https://github.com/tashfeenahmed/freellmapi/blob/main/src/server/src/providers/index.ts)**: Registers the Zhipu provider with the application router, exposing it to the API gateway.
- **[`src/server/src/__tests__/providers/zhipu.test.ts`](https://github.com/tashfeenahmed/freellmapi/blob/main/src/server/src/__tests__/providers/zhipu.test.ts)**: Unit tests verifying the dual-host validation logic and URL resolution behavior.

## Summary

- **FreeLLMAPI treats Zhipu AI as a unified provider** while internally managing two distinct host endpoints.
- **Automatic detection occurs during `validateKey()`**, which probes the domestic host first and falls back to the global host only on authentication failures.
- **The `globalKeys` Set provides in-memory caching**, ensuring only one validation probe per key while the server remains running.
- **Dynamic URL rewriting via `resolveUrl()`** ensures all subsequent requests route to the correct console without manual configuration.
- **The implementation requires zero user configuration**—users provide only their API key, and the system handles host selection transparently.

## Frequently Asked Questions

### How does FreeLLMAPI determine which Zhipu AI host to use?

FreeLLMAPI determines the host by attempting to validate the API key against the domestic `bigmodel.cn` endpoint first. If the validation returns HTTP 401 or 403 errors, it automatically retries against the global `z.ai` endpoint. A successful response from either endpoint identifies the key's namespace, and the provider stores global keys in an in-memory Set for future routing.

### What happens to global key routing after a server restart?

The `globalKeys` Set exists only in memory and does not persist to disk. After a server restart, the first request using a global key will trigger the validation probe sequence again—first attempting the domestic endpoint, failing, then succeeding on the global endpoint. Once validated, the key is added back to the Set for the duration of the session.

### Can users manually specify which Zhipu console to use?

No, FreeLLMAPI does not expose manual host selection to end users. The `ZhipuProvider` automatically discovers the correct host through the validation probing mechanism implemented in [`src/server/src/providers/zhipu.ts`](https://github.com/tashfeenahmed/freellmapi/blob/main/src/server/src/providers/zhipu.ts). This design decision simplifies the API interface while ensuring keys always route to their correct namespaces.

### Does dual-host routing impact request latency?

Only the initial `validateKey()` call incurs potential latency from the double probe (domestic then global). Once validated, subsequent chat completions and streaming requests use the cached routing decision via `resolveUrl()`, adding negligible overhead—a simple Set lookup and string replacement operation.