Overview
Runtime status and pool summary
Accounts
—
Eligible
—
In-flight
—
Throttled
—
Total requests
—
Success rate
—
Avg TTFB
—
OK / failed
—
Output tokens
—
Total quota
—
Balances
Loading…
Recent requests
Loading…
Account Pool
Round-robin · per-account gates · cooldown & exhaustion avoidance
Playground
Pin an account × model, fire real requests through the whole chain
Pick an account and a model, then send a message to verify the whole chain. Leave the account empty for auto round-robin.
Logs
One merged stream: every request and every engine message, in time order
Model Probe
Test which models each account can actually use
Invite Management
Per-account invite registry — codes, owners and manual/round-robin assignment
Local registry only — assignments are reservations made by this panel and do not redeem anything upstream.
Total
—
Active
—
Paused
—
Expired
—
Exhausted
—
Assigned accounts
—
Add an invite (manual)
Paste a code or a full invite URL you already hold. Only manually entered records are created here — the gateway never mints or redeems codes upstream.
Default assignment strategy
Official marketing info
Fetched for the selected account only, when you press the button. Read-only official info — it does not redeem or claim anything.
Pick an account and press Refresh.
Version Changelog
What each version fixed — newest first
Upstream Intel
Official release notes and gate changes — live feed, newest 15 only
Loading…
Batch Login API — for AI agents
Let your AI assistant add accounts in bulk. Copy the prompt below into your coding agent — it knows everything it needs.
How it works (3 steps)
1. Your AI calls POST /admin/api/accounts/login/batch with { "count": N } — the engine opens N login sessions and returns N authorize URLs.
2. A HUMAN opens each URL and signs in to the provider (this step is deliberately manual — the gateway never collects provider passwords). Sessions expire in 5 minutes, so do them promptly.
3. The AI polls POST /admin/api/accounts/login/batch/status with the sessionIds until every entry reports done:true — the engine registers each account automatically on success.
Endpoints
POST /admin/api/accounts/login/batch { "count": 5, "provider": "zai" } (namePrefix 可选:不传=账号名默认用邮箱;自定义名字才传)
POST /admin/api/accounts/login/batch/status { "sessionIds": ["…","…"] }
POST /admin/api/accounts/login/batch/cancel { "sessionIds": ["…"] }
POST /admin/api/accounts/login/batch/status { "sessionIds": ["…","…"] }
POST /admin/api/accounts/login/batch/cancel { "sessionIds": ["…"] }
Auth: same admin key / panel session as every other admin API (Cookie session, or Authorization: Bearer for API-key callers; writes need the x-csrf-token header when cookie-authenticated).
Prompt for your AI (click to select all, then copy)
Batch-add accounts to my ZcodeKnight gateway, FULLY AUTOMATIC.
Gateway: {BASE_URL} (admin key: I will provide it when you ask)
Panel page: {BASE_URL}/admin
Account credentials: I will provide the list (email + password per line) when you ask.
Do this:
1. POST {BASE_URL}/admin/api/accounts/login/batch
Headers: Authorization: Bearer <admin key>, content-type: application/json
Body: {"count": N, "provider": "zai"} (namePrefix OPTIONAL — omit it; accounts default to their email. Pass it only if the user explicitly asks for custom names)
Save every sessionId + authorizeUrl from the response.
2. For each authorizeUrl, open it with your browser automation (Playwright or
browser-use), sign in with THAT account's email + password, and complete
the authorization. Sessions expire 5 minutes after creation — process them
in small waves (e.g. 3-5 at a time) so nothing expires while you work.
3. Poll POST {BASE_URL}/admin/api/accounts/login/batch/status
Body: {"sessionIds": ["<all sessionIds>"]}
Repeat every 5 seconds until summary.pending is 0. Report each account's
ok/error and the final summary. The engine registers every successful
account into the pool automatically — no further calls needed.
4. If some sessions expire before automation finishes, call the batch
endpoint again for just the missing count and repeat steps 2-3.
5. Type credentials ONLY into the provider's own authorize page opened from
its authorizeUrl — never send them to any other endpoint or third party.
Invitation registry API
GET /admin/api/invites?search=&category=&status=&accountId=&page=1&pageSize=20&sort=
GET /admin/api/invites/stats
POST /admin/api/invites { "code"|"url", "label", "category", "tags": [], "campaignId", "status", "maxUses", "expiresAt", "note", "ownerAccountId" }
PATCH /admin/api/invites/:id (any of the fields above; "ownerAccountId": null clears the owner)
POST /admin/api/invites/:id/assign { "accountId", "requestId"? }
POST /admin/api/invites/assign-next { "accountId", "strategy": "round_robin", "category"?, "requestId"? }
POST /admin/api/invites/:id/release { "accountId" }
DELETE /admin/api/invites/:id (409 while a live reservation exists — release first)
POST /admin/api/invites/settings { "defaultStrategy": "manual" | "round_robin" }
GET /admin/api/marketing?accountId=…
GET /admin/api/invites/stats
POST /admin/api/invites { "code"|"url", "label", "category", "tags": [], "campaignId", "status", "maxUses", "expiresAt", "note", "ownerAccountId" }
PATCH /admin/api/invites/:id (any of the fields above; "ownerAccountId": null clears the owner)
POST /admin/api/invites/:id/assign { "accountId", "requestId"? }
POST /admin/api/invites/assign-next { "accountId", "strategy": "round_robin", "category"?, "requestId"? }
POST /admin/api/invites/:id/release { "accountId" }
DELETE /admin/api/invites/:id (409 while a live reservation exists — release first)
POST /admin/api/invites/settings { "defaultStrategy": "manual" | "round_robin" }
GET /admin/api/marketing?accountId=…
Every entry returned by GET /invites carries its own effectiveStatus (active | paused | expired | exhausted), computed from status, expiry and use counts.
Assignments returned by the assign endpoints are LOCAL reservations in this gateway's registry — no endpoint redeems, activates or spends a code upstream, and no count here is an official reward or chance figure.
Writes answer 400 bad_request (malformed expiresAt or field value), 409 duplicate_code / in_use, 404 not_found. A reservation counts against maxUses immediately; release returns it.
Errors are JSON { "error": { "type", "message" } } with
400 (bad request / unknown field), 404 (no such invite), 409 (already assigned to that account) and 401/403 (auth). The mutating calls use the same admin auth as the rest of this page.
Auth: same admin key / panel session as every other admin API (Cookie session, or Authorization: Bearer for API-key callers; writes need the x-csrf-token header when cookie-authenticated).
Prompt for your AI — invitation management (click to select all, then copy)
Manage the invitation registry on my ZcodeKnight gateway, via its admin API only.
Gateway: {BASE_URL} (admin key: I will provide it when you ask)
Panel page: {BASE_URL}/admin (Invite page)
Auth for every call:
- Header: Authorization: Bearer <admin key>
- If you authenticate with the panel Cookie session instead, every POST/PATCH must
also send the x-csrf-token header from the login response.
Contract:
- GET {BASE_URL}/admin/api/invites?search=&category=&status=&accountId=&page=1&pageSize=20&sort=
-> { entries: [{ id, ownerAccountId?, code, url, label, category, tags, source,
campaignId, status, effectiveStatus, maxUses, usedCount, reservedCount,
expiresAt, note, createdAt, updatedAt }], total, page, pageSize, totalPages,
categories, settings: { defaultStrategy }, assignments: [...], accounts: [...] }
- GET {BASE_URL}/admin/api/invites/stats -> { total, active, paused, expired, exhausted, assignedAccounts }
- POST {BASE_URL}/admin/api/invites body { code | url, label?, category?, tags?, campaignId?, status?, maxUses?, expiresAt?, note?, ownerAccountId? } -> { entry }
- PATCH {BASE_URL}/admin/api/invites/:id same fields, partial -> { entry }
- POST {BASE_URL}/admin/api/invites/:id/assign { accountId, requestId? } -> { assignment, entry }
- POST {BASE_URL}/admin/api/invites/assign-next { accountId, strategy: "round_robin", category?, requestId? } -> { assignment, entry }
- POST {BASE_URL}/admin/api/invites/:id/release { accountId } -> { ok }
- POST {BASE_URL}/admin/api/invites/settings { defaultStrategy: "manual" | "round_robin" } -> { settings }
- GET {BASE_URL}/admin/api/marketing?accountId=<id> -> { accountId, fetchedAt, fresh, available, deliveries: [...], error? }
Rules you must follow:
1. This gateway's registry is LOCAL bookkeeping. An assignment returned by the
assign endpoints is a LOCAL reservation, NOT a successful official use, and
nothing here redeems, activates or spends a code upstream. Never report an
assignment as a completed redemption.
2. Never invent official links, rewards or remaining-chance counts. If a field
(expiresAt, maxUses, campaignId, remainingChances, a URL) is null/missing,
say it is unknown.
3. `source` is "manual" for entries an operator entered and "official" for ones
the engine knows about. Only manual entries can be created/edited through
this API.
4. Prefer PATCH for edits; it accepts a partial body. Use an explicit null to
clear an optional field such as ownerAccountId or expiresAt.
5. Do not attempt automatic external redemption, claiming or captcha solving
through these endpoints — the API has no such call, and the Invite page never
performs one.
6. Never send provider passwords anywhere: no endpoint here accepts them.
Settings
Some changes need a proxy restart
适配 ZCode 客户端版本:3.14.4+(身份指纹按此版本伪装;低于此版本可能触发上游 1004 ineligible)
Endpoint (OpenAI format)
Paste into your coding tools
API Key
Paste into your coding tools (copy on the right); empty disables client auth
面板登录密码
登录本面板用的密码;与上面的 API Key 互不影响。留空新密码则恢复用 API Key 登录
Per-account gate
Account-wide ceiling — measured 3, 3008 above it
Per-model ceiling
Default for models with no entry below. Conservative by default (1) — raise it when the accounts tolerate more
Model overrides
One per line, model=limit. glm-5.3 allows only 1 — above that it returns 3009
Overflow factor
When all slots are busy, try up to this multiple of the gate before refusing; a rejection downgrades immediately. 1 = never exceed
Cooldown (seconds)
Backoff after hitting the concurrency limit — applies immediately
Model cooldown (seconds)
Hold on ONE model after a 3009 collision. Kept short on purpose: the condition clears when the competing request finishes
Min spacing per account (ms)
Shortest gap between two requests on one account — lowers risk-control hits; 0 disables
Auto-claim activity quota
Detects activity rounds automatically and claims when one is live; new accounts claim on first sight
Claim all now
One click: detect and claim for every account
Outbound proxy
Route upstream traffic through a trusted proxy when risk control blocks this IP (3012). Applies immediately; loopback always stays direct
Proxy URL
e.g. http://127.0.0.1:7890 or socks5://user:pass@host:1080; empty falls back to the HTTPS_PROXY env var
Spare egress (3012 rotation)
One proxy URL per line. When upstream answers 3012 (IP flagged), the engine switches to the next one automatically — the flagged URL goes to the back of the list. Empty = never rotate
Direct hosts
Comma-separated hosts that bypass the proxy
Panel idle logout
Minutes of inactivity before the panel asks for the key again. Any activity resets the clock; 0 never logs out
Online update
Current version
— · Click “Check for updates”Export & import
Logs export as CSV; data exports as a restorable backup bundle
Export request log
CSV with time, caller IP, account, model, timings and status — opens directly in Excel. Contains no keys
Export all data
Accounts, settings, probe results and config.yaml in one JSON, with a manifest of what was included and skipped. Contains your proxy key — keep it private
Import a backup
The current data is archived to data/backups/ first. The bundle is encrypted with this machine's key, so accounts need a fresh login on another machine