Admin console guide
Configure providers, channels, public models, users, API keys, prepaid credit, quotas, scopes, and model permissions.
The Django Admin is Cordy Gateway's control plane. Only users with the ADMIN or OWNER role can enter it; MEMBER users use the separate self-service portal.
Sign in
The production quickstart creates the first operator with createsuperuser. Open:
http://<admin-host>:<ADMIN_HTTP_PORT>/<DJANGO_ADMIN_URL>
ADMIN_HTTP_PORT defaults to 8001. DJANGO_ADMIN_URL is the private path you configured and must end with /.
Configure an upstream model
A callable public model needs all five records described in Providers:
- Provider — name and provider type, such as
OPENAI,ANTHROPIC,ARK, or another uppercase identifier. - Model — the public slug clients send, such as
gpt-4o-mini. - Provider model — maps that public model to the upstream model ID and capability flags.
- Channel — endpoint, encrypted credential, priority, weight, region, limits, and provider-specific configuration.
- Channel-provider-model — enables the mapped model on that channel.
Example: create provider OpenAI, public model gpt-4o-mini, provider-model ID gpt-4o-mini, and a channel carrying the OpenAI key; then add the channel-provider-model binding. The standard OpenAI integration uses its built-in endpoint. A missing or inactive binding means the model may appear in configuration but cannot be routed.
Use Test connection on the Channel form before handing a model to users. Channel credentials are Fernet-encrypted with CHANNEL_ENCRYPTION_KEYS; the Admin and Gateway must receive the same key set.
Create a member
Open Users → Add and set:
| Field | Default | Operator choice |
|---|---|---|
| Email / password | Required | MEMBER signs in with these at /my/login/ |
| Role | MEMBER | Use ADMIN/OWNER only for operators |
| Status | ACTIVE | INACTIVE or SUSPENDED cannot sign in or call the gateway |
| Tier | free | free, pro, standard, or enterprise |
| Default rate limit | 60 requests/minute | Copied to keys created through /my/ |
| Default token quota | 10,000 | Copied to keys created through /my/ |
| Subscription expiry / plan ID | Empty | Optional account metadata |
| Credit balance | 0 | Read-only; change it through the ledger action |
Add prepaid credit
Credit is the billing gate. In the user list:
- select one or more users;
- enter Top-up USD and an optional reason;
- choose Top up prepaid credit and run the action.
The action updates the balance atomically and appends a topup ledger record. Do not edit the balance directly. Gateway settlement appends negative consume entries; adjustment and refund entries remain visible in the read-only ledger.
Credit and token quota are separate controls: zero credit returns 402 insufficient_credits; an exhausted per-key token quota returns 429 quota_exceeded.
Issue and control API keys
Members can create and revoke their own keys in /my/. Operators can also create a key under API keys or through the inline on a user. Portal-created keys copy the user's default rate and token quota. A key created directly in Admin starts from the API key model defaults—1,000 requests/minute and 10,000 tokens—so set those two fields explicitly when the member needs different limits. The generated wnx_ plaintext appears once; only its SHA-256 hash is stored.
New keys default to these inference scopes:
chatcompletionsembeddingsmodels
Add balance when a client must call balance, subscription, package, or account analytics endpoints. Reserve admin for an explicit administrative integration. An empty scope list is legacy unrestricted behavior; use an explicit least-privilege list.
Per key, review status, expiry, requests-per-minute rate limit, token quota, and quota used. Revoking a key takes effect on its next request.
Restrict models
Use User model permissions to allow or deny public models for a user. The gateway applies this after key authentication and before routing. Test with GET /v1/models using that user's key: the visible list should match the intended permissions.
Set platform-wide self-service limits
Open Users & Access → Platform settings. max_api_keys_per_user defaults to 3 and limits how many key records a member can create in /my/. The current count includes revoked and inactive keys, so revoking a key does not free a portal creation slot. The same page shows read-only license status and evidence. Keep one Platform settings record and change this limit before onboarding users who need more keys.
Maintain pricing
Open Gateway Config → Price audit, or edit the Price history inline on a provider model. Price history is the authoritative source for request-time cost snapshots and cost reporting; the older price columns on Provider model are hidden and are not used for cost.
For each price row, set:
- the provider model;
- input and output price per 1,000 tokens;
- a three-letter currency and its positive conversion rate to USD;
effective_fromand optional exclusiveeffective_totimestamps;- source: manual, provider sync, or invoice adjustment.
Effective windows for the same provider model cannot overlap. To change a price without rewriting history, close the current row at the new price's start time and add a new row beginning at that same time. Requests without an effective row keep an explicit unknown-cost status.
Current-source limitation: cheapest routing still scores the hidden legacy Provider model price columns instead of Price history. Editing Price history updates metering and settlement evidence, but does not update that routing input. Do not treat cheapest as controlled by the Price audit screen in this source snapshot; validate the strategy against your distribution before enabling it.
Review monitoring evidence
The Admin provides these operator views:
| View | Use | Write behavior |
|---|---|---|
| Platform overview / Usage & cost | High-level request, token, cost, and health summaries | Dashboard only |
| Request logs | Search request ID, user, key, channel, status, latency, token, cost, and optional trace link | Read-only |
| Usage stats | Inspect daily request/token/cost aggregates | Read-only |
| Channel health | Inspect channel health evidence before changing routing configuration | Operational evidence |
| Audit log | Review actor, object, action, timestamp, and change details | Append-only and read-only in Admin |
Use the operations guide to diagnose a request. Do not edit evidence records to make a dashboard reconcile.
Import and reconcile upstream invoices
The Cost Reconciliation Admin pages are read-only. First copy the summarized invoice CSV or JSON into the Admin container, then run the import:
The required columns are provider, period_start, period_end, and billed_amount. period_end must be later than period_start. Optional fields are currency (default USD), fx_rate_to_usd (default 1), request_count, prompt_tokens, completion_tokens, total_tokens, and JSON-object metadata. For example:
provider,period_start,period_end,currency,billed_amount,fx_rate_to_usd,request_count,prompt_tokens,completion_tokens,total_tokens
openai-main,2026-08-01,2026-09-01,USD,42.50,1,1200,800000,200000,1000000
docker compose -f docker-compose.prod.yml -f docker-compose.production-overrides.yml --env-file .env cp \
./invoice.csv admin:/tmp/invoice.csv
docker compose -f docker-compose.prod.yml -f docker-compose.production-overrides.yml --env-file .env exec admin \
uv run python manage.py import_upstream_invoice /tmp/invoice.csv \
--format auto --imported-by-email operator@example.com --output table
--format accepts auto, csv, or json; repeated source rows are skipped using their evidence identity. Then compare one provider and an inclusive-start/exclusive-end billing period:
docker compose -f docker-compose.prod.yml -f docker-compose.production-overrides.yml --env-file .env exec admin \
uv run python manage.py reconcile_upstream_invoice \
--provider openai-main --start 2026-08-01 --end 2026-09-01 \
--threshold-absolute-usd 1.00 --threshold-percentage 5.0 \
--created-by-email operator@example.com --format table
The default drift thresholds are USD 1.00 and 5.0%. Add --no-persist for a preview; omit it to create the read-only Reconciliation run shown in Admin. Reconciliation compares internal request-time cost evidence with the imported invoice total. It does not alter member balances, prices, or request logs.
For an operator-only breakdown before reconciliation, run:
docker compose -f docker-compose.prod.yml -f docker-compose.production-overrides.yml --env-file .env exec admin \
uv run python manage.py usage_cost_report \
--group-by day,provider,model \
--start 2026-08-01T00:00:00Z --end 2026-09-01T00:00:00Z \
--format table
The start is inclusive and the end is exclusive. Filters are also available for user, API key, channel, model, provider, and status.
Understand advanced records
- Prompt templates, versions, and experiments can be created by platform operators, but current Gateway request code does not read them or inject them into chat/completions. They are a stored control-plane registry today; changing one does not change live inference.
- Test runs and test artifacts are read-only records imported by the internal quality-run tooling. They do not configure customer traffic.
- Eval results are read-only evaluator output attached to request evidence. They are not routing, billing, or prompt controls.
Treat these pages as internal evidence/registry surfaces unless a future release connects them to a supported request path.
Verify onboarding
As the member:
- sign in at
/my/login/; - create a key and copy its one-time plaintext;
- confirm balance and recent usage;
- call
GET /v1/models; - make a text-only
POST /v1/chat/completions; - confirm the request appears under portal Usage and the prepaid ledger is debited.
See Operations for health checks and diagnosis.