Preview: https://nodew.lezi.chat
The preview link points to a temporary test deployment for trying the current UI and API flow. It is not a production service.
NodEW-api is a Node.js and TypeScript edition of the One API gateway, focused on OpenAI-compatible relay, multi-provider channel routing, token management, usage logging, and web-based administration.
Repository: https://github.com/lezi-fun/nodew-api
Based on One API: https://github.com/songquanpeng/one-api
Copyright 2026 lezi-fun Team. Licensed under the Apache License, Version 2.0.
NodEW-api is still in early-stage development. It is not recommended for production use yet. APIs, database schemas, configuration, and deployment behavior may receive breaking changes at any time without prior notice. Contributions, testing feedback, and issue reports are welcome.
Serverless deployment support is under active development.
This project is a Node.js/TypeScript adaptation of One API. The codebase is built around Fastify, Prisma, TypeScript, React, Vite, and Semi UI.
Current capabilities include:
- OpenAI-compatible relay endpoints under
/v1, including chat completions and streaming responses. - Channel management with provider metadata, weights, priorities, health checks, and model sync.
- Token management with quota, expiry, and model allow/block metadata.
- Account security flows, including email verification, password reset, 2FA, Passkey, and session management.
- Verified email rebinding from the personal page, with both mail-link and verification-code completion paths.
- Third-party login for GitHub, Discord, LinuxDO, OIDC, and admin-defined OAuth providers with callback handling, automatic account creation, and bind-mode support for authenticated sessions.
- Admin-managed custom OAuth provider configuration with runtime field mapping, token auth style, and access-policy checks.
- Personal-page third-party account binding status plus self-service unbind support.
- Admin-side inspection and removal for user third-party account bindings.
- Daily check-in with configurable random quota rewards, monthly history, and streak statistics.
- Wallet page with balance metrics, recharge plan overview, Stripe Checkout top-up, payment-method status, and redemption-code top-up.
- Usage logs and billing-oriented request accounting.
- Admin console for dashboard, channels, tokens, users, redemptions, logs, models, deployment, settings, wallet, and playground.
- The settings console is split into linkable business domains: general/operations, authentication/mail, OAuth, and subscriptions/billing.
- PostgreSQL by default, with a dedicated MySQL Prisma schema for MySQL deployments.
- Node.js 22 or newer
- npm
- PostgreSQL for the default setup
- Optional: MySQL if using the MySQL Prisma schema
Early-stage warning: NodEW-api is not recommended for production use yet. APIs, database schemas, configuration, and deployment behavior may receive breaking changes at any time without prior notice.
Install dependencies:
npm install
cd web
npm install
cd ..Create .env:
NODE_ENV=development
HOST=0.0.0.0
PORT=3000
LOG_LEVEL=info
DATABASE_URL="postgresql://postgres:postgres@localhost:5432/nodew_api?schema=public"
SESSION_SECRET="nodew-dev-session-secret"Email delivery now supports either SMTP or Resend. Configure one provider when you want password reset, email verification, and pre-registration verification messages to be sent automatically.
If you do not want to keep the mail settings only in environment variables, the admin settings page can now manage the mail configuration directly. Saved values take effect immediately, while environment variables continue to act as defaults and fallbacks.
APP_BASE_URL="http://127.0.0.1:3000"
MAIL_PROVIDER="smtp"
MAIL_FROM="noreply@example.com"
SMTP_HOST="smtp.example.com"
SMTP_PORT=587
SMTP_SECURE=false
SMTP_USER="smtp-user"
SMTP_PASS="smtp-password"Or use Resend:
APP_BASE_URL="http://127.0.0.1:3000"
MAIL_PROVIDER="resend"
MAIL_FROM="noreply@example.com"
RESEND_API_KEY="re_xxx"If you plan to require email verification before registration from the admin settings page, make sure mail delivery is configured first. When this option is enabled:
- Users must open the verification link from the email or enter the verification code on the registration page.
- The account is created only after verification succeeds.
- The settings page shows current mail delivery status and includes a test-mail action.
The admin settings page also includes a dedicated check-in section:
checkin_enabledcontrols whether the personal page shows the check-in entry.checkin_min_quotaandcheckin_max_quotadefine the random reward range for each successful check-in.- The personal page shows current status, calendar history, monthly totals, and streak statistics.
The same settings page now includes a Passkey section:
passkey_enabledtoggles whether Passkey registration and login are available.passkey_rp_display_name,passkey_rp_id, andpasskey_originscontrol WebAuthn relying-party identity.passkey_user_verificationandpasskey_attachment_preferencetune registration/authenticator behavior.
Sensitive security actions on the personal page now use a shared verification dialog:
- Disabling 2FA
- Regenerating 2FA backup codes
- Deleting Passkey
Users can complete this verification with either a 2FA code / backup code or a Passkey. The backend also enforces the same verification window, so calling these endpoints directly without a fresh verification state is rejected.
Third-party login is available through environment variables. OIDC can also be edited later from the admin settings page. Set APP_BASE_URL plus the credentials for each provider you want to enable:
APP_BASE_URL="http://127.0.0.1:3000"
GITHUB_OAUTH_CLIENT_ID="Iv1.xxxxx"
GITHUB_OAUTH_CLIENT_SECRET="github-oauth-secret"
DISCORD_OAUTH_CLIENT_ID="discord-client-id"
DISCORD_OAUTH_CLIENT_SECRET="discord-client-secret"
LINUXDO_OAUTH_CLIENT_ID="linuxdo-client-id"
LINUXDO_OAUTH_CLIENT_SECRET="linuxdo-client-secret"
OIDC_OAUTH_ENABLED=true
OIDC_OAUTH_WELL_KNOWN_URL="https://id.example.com/.well-known/openid-configuration"
OIDC_OAUTH_CLIENT_ID="oidc-client-id"
OIDC_OAUTH_CLIENT_SECRET="oidc-client-secret"
OIDC_OAUTH_AUTHORIZATION_URL="https://id.example.com/oauth2/authorize"
OIDC_OAUTH_TOKEN_URL="https://id.example.com/oauth2/token"
OIDC_OAUTH_USERINFO_URL="https://id.example.com/oauth2/userinfo"
OIDC_OAUTH_SCOPE="openid profile email"When a provider is configured, the login page shows its entry button and the backend enables /api/oauth/state plus /api/oauth/:provider. The callback route also supports bind-mode when the request already has an authenticated session. OIDC userinfo must return sub and email; preferred_username, name, picture, and email_verified are used when present. The admin settings page can save OIDC client credentials and endpoints, and can fetch endpoints from a Well-Known discovery document.
Custom OAuth providers are configured from the admin settings page. Their callback path is /oauth/{slug}. Field mappings support dot paths such as data.user.id and array indexes such as groups[0]. Access policies accept either a single condition like {"field":"groups","operator":"contains","value":"staff"} or grouped policies with logic, conditions, and groups. Supported operators are eq, ne, gt, gte, lt, lte, in, not_in, contains, not_contains, exists, and not_exists.
Stripe wallet top-up can be enabled with environment variables. The wallet page creates a Stripe-hosted Checkout Session, and the webhook credits quota only after Stripe confirms payment.
APP_BASE_URL="https://your-domain.example"
STRIPE_TOPUP_ENABLED=true
STRIPE_SECRET_KEY="sk_live_xxx"
STRIPE_WEBHOOK_SECRET="whsec_xxx"
STRIPE_CURRENCY="usd"
STRIPE_QUOTA_PER_UNIT=100000
STRIPE_UNIT_AMOUNT_CENTS=100
STRIPE_MIN_UNITS=1Configure the Stripe webhook endpoint as https://your-domain.example/api/user/topup/stripe/webhook. The backend handles checkout.session.completed, checkout.session.async_payment_succeeded, checkout.session.expired, and checkout.session.async_payment_failed, and webhook delivery is idempotent for paid orders.
Creem wallet top-up product configuration can also be prepared with environment variables. The backend exposes the configured product catalog, creates Checkout Sessions for configured products, and credits quota from signed Creem webhook events.
APP_BASE_URL="https://your-domain.example"
CREEM_TOPUP_ENABLED=true
CREEM_API_KEY="creem_xxx"
CREEM_WEBHOOK_SECRET="creem_whsec_xxx"
CREEM_TEST_MODE=false
CREEM_PRODUCTS='[{"productId":"prod_xxx","name":"100k quota","quotaAmount":100000,"amountCents":1000,"currency":"usd"}]'Configure the Creem webhook endpoint as https://your-domain.example/api/user/topup/creem/webhook. Paid checkout.completed events are idempotent and credit quota only while the matching order is still pending.
Waffo wallet top-up uses the same fixed-product shape. The backend exposes the safe catalog, the console can start hosted checkout orders, and signed webhook payment events settle quota automatically.
APP_BASE_URL="https://your-domain.example"
WAFFO_TOPUP_ENABLED=true
WAFFO_API_KEY="waffo_xxx"
WAFFO_PRIVATE_KEY="base64_pkcs8_private_key"
WAFFO_PUBLIC_KEY="base64_x509_public_key"
WAFFO_TEST_MODE=false
WAFFO_PRODUCTS='[{"productId":"prod_xxx","name":"100k quota","quotaAmount":100000,"amountCents":1000,"currency":"usd"}]'Prepare Prisma:
npm run prisma:generate
npm run prisma:migrate:deployBuild the web console:
cd web
npm run build
cd ..Start the server:
npm run devOpen http://127.0.0.1:3000.
In development, the server automatically ensures this admin account exists:
Email: test@test.com
Password: testtest
The development seed is non-destructive: it upserts the default admin and setup state without deleting channels, tokens, users, or logs.
cd web
npm run build
cd ..
npm run build
npm run startnpm run start serves the compiled backend and the built frontend from web/dist on the configured HOST and PORT.
Vercel support is experimental while the Serverless deployment path is under active development.
The repository includes:
vercel.json: build, function, and rewrite configuration.api/server.js: Vercel Function entrypoint for the compiled Fastify app.installCommand: uses Bun to install both root backend dependencies andwebfrontend dependencies.bun run vercel-build: generates Prisma Client, applies production Prisma migrations, builds the backend, and builds the web console.
Required Vercel environment variables:
NODE_ENV=production
LOG_LEVEL=info
DATABASE_URL="postgresql://USER:PASSWORD@HOST:PORT/DATABASE?schema=public"
SESSION_SECRET="replace-with-a-long-random-secret"
CHANNEL_SECRET="replace-with-a-long-random-secret"Use an external PostgreSQL provider such as Neon, Supabase, RDS, Railway, or another managed database. Do not use a localhost database on Vercel.
Run migrations against the production database before deploying:
DATABASE_URL="postgresql://USER:PASSWORD@HOST:PORT/DATABASE?schema=public" npm run prisma:migrate:deployVercel routes /api/*, /v1/*, /v1beta/*, /health, and /ready to the Fastify function. Other paths are served by the built SPA from web/dist.
PostgreSQL is the default provider:
npm run prisma:generate:postgres
npm run prisma:migrate:deploy:postgresMySQL is supported through a dedicated schema:
export DATABASE_URL="mysql://nodew_api:nodew_api@localhost:3306/nodew_api"
npm run prisma:generate:mysql
npm run prisma:migrate:deploy:mysqlOnly one Prisma provider is active in a built deployment. Regenerate the Prisma Client after switching providers.
npm run dev
npm run build
npm run start
npm testWeb console commands:
cd web
npm run dev
npm run build
npm run previewRelay endpoints:
GET /v1/modelsPOST /v1/chat/completionsPOST /v1/completionsPOST /v1/embeddingsPOST /v1/responsesPOST /v1/images/generationsPOST /v1/audio/speechPOST /v1/audio/transcriptionsPOST /v1/audio/translations
Admin and console APIs are exposed under /api.
Account utility endpoints:
GET /api/checkin/statusPOST /api/checkinGET /api/user/passkeyPOST /api/user/passkey/register/beginPOST /api/user/passkey/register/finishPOST /api/user/passkey/login/beginPOST /api/user/passkey/login/finishPOST /api/user/passkey/verify/beginPOST /api/user/passkey/verify/finishDELETE /api/user/passkeyPOST /api/user/2fa/disablePOST /api/user/2fa/backup-codesPOST /api/verify
Apache License 2.0. See LICENSE.