sk-ant-sid01-',
startAutoAuth: 'Start Auto-Auth',
authorizing: 'Authorizing...',
followSteps: 'Follow these steps to authorize your Claude account:',
step1GenerateUrl: 'Click the button below to generate the authorization URL',
generateAuthUrl: 'Generate Auth URL',
generating: 'Generating...',
regenerate: 'Regenerate',
step2OpenUrl: 'Open the URL in your browser and complete authorization',
openUrlDesc:
'Open the authorization URL in a new tab, log in to your Claude account and authorize.',
proxyWarning:
'Note: If you configured a proxy, make sure your browser uses the same proxy to access the authorization page.',
step3EnterCode: 'Enter the Authorization Code',
authCodeDesc:
'After authorization is complete, the page will display an Authorization Code. Copy and paste it below:',
authCode: 'Authorization Code',
authCodePlaceholder: 'Paste the Authorization Code from Claude page...',
authCodeHint: 'Paste the Authorization Code copied from the Claude page',
completeAuth: 'Complete Authorization',
verifying: 'Verifying...',
pleaseEnterSessionKey: 'Please enter at least one valid sessionKey',
authFailed: 'Authorization failed',
cookieAuthFailed: 'Cookie authorization failed',
keyAuthFailed: 'Key {index}: {error}',
successCreated: 'Successfully created {count} account(s)',
// OpenAI specific
openai: {
title: 'OpenAI Account Authorization',
followSteps: 'Follow these steps to complete OpenAI account authorization:',
step1GenerateUrl: 'Click the button below to generate the authorization URL',
generateAuthUrl: 'Generate Auth URL',
step2OpenUrl: 'Open the URL in your browser and complete authorization',
openUrlDesc:
'Open the authorization URL in a new tab, log in to your OpenAI account and authorize.',
importantNotice:
'Important: The page may take a while to load after authorization. Please wait patiently. When the browser address bar changes to http://localhost..., the authorization is complete.',
step3EnterCode: 'Enter Authorization URL or Code',
authCodeDesc:
'After authorization is complete, when the page URL becomes http://localhost:xxx/auth/callback?code=...:',
authCode: 'Authorization URL or Code',
authCodePlaceholder:
'Option 1: Copy the complete URL\n(http://localhost:xxx/auth/callback?code=...)\nOption 2: Copy only the code parameter value',
authCodeHint:
'You can copy the entire URL or just the code parameter value, the system will auto-detect'
},
// Gemini specific
gemini: {
title: 'Gemini Account Authorization',
followSteps: 'Follow these steps to authorize your Gemini account:',
step1GenerateUrl: 'Generate the authorization URL',
generateAuthUrl: 'Generate Auth URL',
projectIdLabel: 'Project ID (optional)',
projectIdPlaceholder: 'e.g. my-gcp-project or cloud-ai-companion-xxxxx',
projectIdHint:
'Leave empty to auto-detect after code exchange. If auto-detection fails, fill it in and re-generate the auth URL to try again.',
howToGetProjectId: 'How to get',
step2OpenUrl: 'Open the URL in your browser and complete authorization',
openUrlDesc:
'Open the authorization URL in a new tab, log in to your Google account and authorize.',
step3EnterCode: 'Enter Authorization URL or Code',
authCodeDesc:
'After authorization, copy the callback URL (recommended) or just the code and paste it below.',
authCode: 'Callback URL or Code',
authCodePlaceholder:
'Option 1 (recommended): Paste the callback URL\nOption 2: Paste only the code value',
authCodeHint: 'The system will auto-extract code/state from the URL.',
redirectUri: 'Redirect URI',
redirectUriHint:
'This must be configured in your Google OAuth client and must match exactly.',
confirmRedirectUri:
'I have configured this Redirect URI in the Google OAuth client (must match exactly)',
invalidRedirectUri: 'Redirect URI must be a valid http(s) URL',
redirectUriNotConfirmed: 'Please confirm the Redirect URI is configured correctly',
missingRedirectUri: 'Missing redirect URI',
failedToGenerateUrl: 'Failed to generate Gemini auth URL',
missingExchangeParams: 'Missing auth code, session ID, or state',
failedToExchangeCode: 'Failed to exchange Gemini auth code',
modelPassthrough: 'Gemini Model Passthrough',
modelPassthroughDesc:
'All model requests are forwarded directly to the Gemini API without model restrictions or mappings.',
stateWarningTitle: 'Note',
stateWarningDesc: 'Recommended: paste the full callback URL (includes code & state).',
oauthTypeLabel: 'OAuth Type',
needsProjectId: 'For GCP Developers',
needsProjectIdDesc: 'Requires GCP project',
noProjectIdNeeded: 'For Regular Users',
noProjectIdNeededDesc: 'Requires admin-configured OAuth client',
aiStudioNotConfiguredShort: 'Not configured',
aiStudioNotConfiguredTip:
'AI Studio OAuth is not configured: set GEMINI_OAUTH_CLIENT_ID / GEMINI_OAUTH_CLIENT_SECRET and add Redirect URI: http://localhost:1455/auth/callback (Consent screen scopes must include https://www.googleapis.com/auth/generative-language.retriever)',
aiStudioNotConfigured:
'AI Studio OAuth is not configured: set GEMINI_OAUTH_CLIENT_ID / GEMINI_OAUTH_CLIENT_SECRET and add Redirect URI: http://localhost:1455/auth/callback'
},
// Antigravity specific
antigravity: {
title: 'Antigravity Account Authorization',
followSteps: 'Follow these steps to authorize your Antigravity account:',
step1GenerateUrl: 'Generate the authorization URL',
generateAuthUrl: 'Generate Auth URL',
step2OpenUrl: 'Open the URL in your browser and complete authorization',
openUrlDesc: 'Open the authorization URL in a new tab, log in to your Google account and authorize.',
importantNotice:
'Important: The page may take a while to load after authorization. Please wait patiently. When the browser address bar shows http://localhost..., authorization is complete.',
step3EnterCode: 'Enter Authorization URL or Code',
authCodeDesc:
'After authorization, when the page URL becomes http://localhost:xxx/auth/callback?code=...:',
authCode: 'Authorization URL or Code',
authCodePlaceholder:
'Option 1: Copy the complete URL\n(http://localhost:xxx/auth/callback?code=...)\nOption 2: Copy only the code parameter value',
authCodeHint: 'You can copy the entire URL or just the code parameter value, the system will auto-detect',
failedToGenerateUrl: 'Failed to generate Antigravity auth URL',
missingExchangeParams: 'Missing code, session ID, or state',
failedToExchangeCode: 'Failed to exchange Antigravity auth code'
}
},
// Gemini specific (platform-wide)
gemini: {
modelPassthrough: 'Gemini Model Passthrough',
modelPassthroughDesc:
'All model requests are forwarded directly to the Gemini API without model restrictions or mappings.',
baseUrlHint: 'Leave default for official Gemini API',
apiKeyHint: 'Your Gemini API Key (starts with AIza)'
},
// Re-Auth Modal
reAuthorizeAccount: 'Re-Authorize Account',
claudeCodeAccount: 'Claude Code Account',
openaiAccount: 'OpenAI Account',
geminiAccount: 'Gemini Account',
antigravityAccount: 'Antigravity Account',
inputMethod: 'Input Method',
reAuthorizedSuccess: 'Account re-authorized successfully',
// Test Modal
testAccountConnection: 'Test Account Connection',
account: 'Account',
readyToTest: 'Ready to test. Click "Start Test" to begin...',
connectingToApi: 'Connecting to API...',
testCompleted: 'Test completed successfully!',
testFailed: 'Test failed',
connectedToApi: 'Connected to API',
usingModel: 'Using model: {model}',
sendingTestMessage: 'Sending test message: "hi"',
response: 'Response:',
startTest: 'Start Test',
testing: 'Testing...',
retry: 'Retry',
copyOutput: 'Copy output',
startingTestForAccount: 'Starting test for account: {name}',
testAccountTypeLabel: 'Account type: {type}',
selectTestModel: 'Select Test Model',
testModel: 'Test model',
testPrompt: 'Prompt: "hi"',
// Stats Modal
viewStats: 'View Stats',
usageStatistics: 'Usage Statistics',
last30DaysUsage: 'Last 30 days usage statistics (based on actual usage days)',
stats: {
totalCost: '30-Day Total Cost',
accumulatedCost: 'Accumulated cost',
standardCost: 'Standard',
totalRequests: '30-Day Total Requests',
totalCalls: 'Total API calls',
avgDailyCost: 'Daily Avg Cost',
basedOnActualDays: 'Based on {days} actual usage days',
avgDailyRequests: 'Daily Avg Requests',
avgDailyUsage: 'Average daily usage',
todayOverview: 'Today Overview',
cost: 'Cost',
requests: 'Requests',
tokens: 'Tokens',
highestCostDay: 'Highest Cost Day',
highestRequestDay: 'Highest Request Day',
date: 'Date',
accumulatedTokens: 'Accumulated Tokens',
totalTokens: '30-Day Total',
dailyAvgTokens: 'Daily Average',
performance: 'Performance',
avgResponseTime: 'Avg Response',
daysActive: 'Days Active',
recentActivity: 'Recent Activity',
todayRequests: 'Today Requests',
todayTokens: 'Today Tokens',
todayCost: 'Today Cost',
usageTrend: '30-Day Cost & Request Trend',
noData: 'No usage data available for this account'
},
usageWindow: {
statsTitle: '5-Hour Window Usage Statistics',
gemini3Pro: 'G3P',
gemini3Flash: 'G3F',
gemini3Image: 'G3I',
claude45: 'C4.5'
},
tier: {
free: 'Free',
pro: 'Pro',
ultra: 'Ultra'
}
},
// Proxies
proxies: {
title: 'Proxy Management',
description: 'Manage proxy servers for accounts',
createProxy: 'Create Proxy',
editProxy: 'Edit Proxy',
deleteProxy: 'Delete Proxy',
searchProxies: 'Search proxies...',
allProtocols: 'All Protocols',
allStatus: 'All Status',
columns: {
name: 'Name',
protocol: 'Protocol',
address: 'Address',
status: 'Status',
actions: 'Actions'
},
testConnection: 'Test Connection',
batchTest: 'Test All Proxies',
testFailed: 'Failed',
name: 'Name',
protocol: 'Protocol',
host: 'Host',
port: 'Port',
username: 'Username (Optional)',
password: 'Password (Optional)',
status: 'Status',
enterProxyName: 'Enter proxy name',
leaveEmptyToKeep: 'Leave empty to keep current',
optionalAuth: 'Optional authentication',
form: {
hostPlaceholder: 'proxy.example.com',
portPlaceholder: '8080'
},
noProxiesYet: 'No proxies yet',
createFirstProxy: 'Create your first proxy to route traffic through it.',
// Batch import
standardAdd: 'Standard Add',
batchAdd: 'Quick Add',
batchInput: 'Proxy List',
batchInputPlaceholder:
"Enter one proxy per line in the following formats:\nsocks5://user:pass{'@'}192.168.1.1:1080\nhttp://192.168.1.1:8080\nhttps://user:pass{'@'}proxy.example.com:443",
batchInputHint:
"Supports http, https, socks5 protocols. Format: protocol://[user:pass{'@'}]host:port",
parsedCount: '{count} valid',
invalidCount: '{count} invalid',
duplicateCount: '{count} duplicate',
importing: 'Importing...',
importProxies: 'Import {count} proxies',
batchImportSuccess: 'Successfully imported {created} proxies, skipped {skipped} duplicates',
batchImportAllSkipped: 'All {skipped} proxies already exist, skipped import',
failedToImport: 'Failed to batch import',
// Other messages
creating: 'Creating...',
updating: 'Updating...',
proxyCreated: 'Proxy created successfully',
proxyUpdated: 'Proxy updated successfully',
proxyDeleted: 'Proxy deleted successfully',
proxyWorking: 'Proxy is working!',
proxyWorkingWithLatency: 'Proxy is working! Latency: {latency}ms',
proxyTestFailed: 'Proxy test failed',
failedToLoad: 'Failed to load proxies',
failedToCreate: 'Failed to create proxy',
failedToUpdate: 'Failed to update proxy',
failedToDelete: 'Failed to delete proxy',
failedToTest: 'Failed to test proxy',
deleteConfirm:
"Are you sure you want to delete '{name}'? Accounts using this proxy will have their proxy removed."
},
// Redeem Codes
redeem: {
title: 'Redeem Code Management',
description: 'Generate and manage redeem codes',
generateCodes: 'Generate Codes',
searchCodes: 'Search codes...',
allTypes: 'All Types',
allStatus: 'All Status',
balance: 'Balance',
concurrency: 'Concurrency',
subscription: 'Subscription',
unused: 'Unused',
used: 'Used',
columns: {
code: 'Code',
type: 'Type',
value: 'Value',
status: 'Status',
usedBy: 'Used By',
usedAt: 'Used At',
actions: 'Actions'
},
userPrefix: 'User #{id}',
exportCsv: 'Export CSV',
deleteAllUnused: 'Delete All Unused Codes',
deleteCode: 'Delete Redeem Code',
deleteCodeConfirm:
'Are you sure you want to delete this redeem code? This action cannot be undone.',
deleteAllUnusedConfirm:
'Are you sure you want to delete all unused (active) redeem codes? This action cannot be undone.',
deleteAll: 'Delete All',
generateCodesTitle: 'Generate Redeem Codes',
generatedSuccessfully: 'Generated Successfully',
codesCreated: '{count} redeem code(s) created',
codeType: 'Code Type',
amount: 'Amount ($)',
value: 'Value',
count: 'Count',
generating: 'Generating...',
generate: 'Generate',
copyAll: 'Copy All',
copied: 'Copied!',
download: 'Download',
codesExported: 'Codes exported successfully',
codeDeleted: 'Redeem code deleted successfully',
codesDeleted: 'Successfully deleted {count} unused code(s)',
noUnusedCodes: 'No unused codes to delete',
failedToLoad: 'Failed to load redeem codes',
failedToGenerate: 'Failed to generate codes',
failedToExport: 'Failed to export codes',
failedToDelete: 'Failed to delete code',
failedToDeleteUnused: 'Failed to delete unused codes',
failedToCopy: 'Failed to copy codes',
selectGroup: 'Select Group',
selectGroupPlaceholder: 'Choose a subscription group',
validityDays: 'Validity Days',
groupRequired: 'Please select a subscription group',
days: ' days'
},
// Usage Records
usage: {
title: 'Usage Records',
description: 'View and manage all user usage records',
userFilter: 'User',
searchUserPlaceholder: 'Search user by email...',
selectedUser: 'Selected',
user: 'User',
account: 'Account',
group: 'Group',
requestId: 'Request ID',
requestIdCopied: 'Request ID copied',
allModels: 'All Models',
allAccounts: 'All Accounts',
allGroups: 'All Groups',
allTypes: 'All Types',
allBillingTypes: 'All Billing',
inputCost: 'Input Cost',
outputCost: 'Output Cost',
cacheCreationCost: 'Cache Creation Cost',
cacheReadCost: 'Cache Read Cost',
inputTokens: 'Input Tokens',
outputTokens: 'Output Tokens',
cacheCreationTokens: 'Cache Creation Tokens',
cacheReadTokens: 'Cache Read Tokens',
failedToLoad: 'Failed to load usage records'
},
// Settings
settings: {
title: 'System Settings',
description: 'Manage registration, email verification, default values, and SMTP settings',
registration: {
title: 'Registration Settings',
description: 'Control user registration and verification',
enableRegistration: 'Enable Registration',
enableRegistrationHint: 'Allow new users to register',
emailVerification: 'Email Verification',
emailVerificationHint: 'Require email verification for new registrations'
},
turnstile: {
title: 'Cloudflare Turnstile',
description: 'Bot protection for login and registration',
enableTurnstile: 'Enable Turnstile',
enableTurnstileHint: 'Require Cloudflare Turnstile verification',
siteKey: 'Site Key',
secretKey: 'Secret Key',
siteKeyHint: 'Get this from your Cloudflare Dashboard',
secretKeyHint: 'Server-side verification key (keep this secret)'
},
defaults: {
title: 'Default User Settings',
description: 'Default values for new users',
defaultBalance: 'Default Balance',
defaultBalanceHint: 'Initial balance for new users',
defaultConcurrency: 'Default Concurrency',
defaultConcurrencyHint: 'Maximum concurrent requests for new users'
},
site: {
title: 'Site Settings',
description: 'Customize site branding',
siteName: 'Site Name',
siteNamePlaceholder: 'Sub2API',
siteNameHint: 'Displayed in emails and page titles',
siteSubtitle: 'Site Subtitle',
siteSubtitlePlaceholder: 'Subscription to API Conversion Platform',
siteSubtitleHint: 'Displayed on login and register pages',
apiBaseUrl: 'API Base URL',
apiBaseUrlPlaceholder: 'https://api.example.com',
apiBaseUrlHint:
'Used for "Use Key" and "Import to CC Switch" features. Leave empty to use current site URL.',
contactInfo: 'Contact Info',
contactInfoPlaceholder: 'e.g., QQ: 123456789',
contactInfoHint: 'Customer support contact info, displayed on redeem page, profile, etc.',
docUrl: 'Documentation URL',
docUrlPlaceholder: 'https://docs.example.com',
docUrlHint: 'Link to your documentation site. Leave empty to hide the documentation link.',
siteLogo: 'Site Logo',
uploadImage: 'Upload Image',
remove: 'Remove',
logoHint: 'PNG, JPG, or SVG. Max 300KB. Recommended: 80x80px square image.',
logoSizeError: 'Image size exceeds 300KB limit ({size}KB)',
logoTypeError: 'Please select an image file',
logoReadError: 'Failed to read the image file'
},
smtp: {
title: 'SMTP Settings',
description: 'Configure email sending for verification codes',
testConnection: 'Test Connection',
testing: 'Testing...',
host: 'SMTP Host',
hostPlaceholder: 'smtp.gmail.com',
port: 'SMTP Port',
portPlaceholder: '587',
username: 'SMTP Username',
usernamePlaceholder: "your-email{'@'}gmail.com",
password: 'SMTP Password',
passwordPlaceholder: '********',
passwordHint: 'Leave empty to keep existing password',
fromEmail: 'From Email',
fromEmailPlaceholder: "noreply{'@'}example.com",
fromName: 'From Name',
fromNamePlaceholder: 'Sub2API',
useTls: 'Use TLS',
useTlsHint: 'Enable TLS encryption for SMTP connection'
},
testEmail: {
title: 'Send Test Email',
description: 'Send a test email to verify your SMTP configuration',
recipientEmail: 'Recipient Email',
recipientEmailPlaceholder: "test{'@'}example.com",
sendTestEmail: 'Send Test Email',
sending: 'Sending...',
enterRecipientHint: 'Please enter a recipient email address'
},
adminApiKey: {
title: 'Admin API Key',
description: 'Global API key for external system integration with full admin access',
notConfigured: 'Admin API key not configured',
configured: 'Admin API key is active',
currentKey: 'Current Key',
regenerate: 'Regenerate',
regenerating: 'Regenerating...',
delete: 'Delete',
deleting: 'Deleting...',
create: 'Create Key',
creating: 'Creating...',
regenerateConfirm: 'Are you sure? The current key will be immediately invalidated.',
deleteConfirm:
'Are you sure you want to delete the admin API key? External integrations will stop working.',
keyGenerated: 'New admin API key generated',
keyDeleted: 'Admin API key deleted',
copyKey: 'Copy Key',
keyCopied: 'Key copied to clipboard',
keyWarning: 'This key will only be shown once. Please copy it now.',
securityWarning: 'Warning: This key provides full admin access. Keep it secure.',
usage: 'Usage: Add to request header - x-api-key: Sub2API is a powerful AI service gateway platform that helps you easily manage and distribute AI services.
🎯 Core Features:
Let\'s complete the initial setup in 3 minutes →
What is a Group?
Groups are the core concept of Sub2API, like a "service package":
💡 Example: You can create "VIP Premium" (high rate) and "Free Trial" (low rate) groups
👉 Click "Group Management" on the left sidebar
Let\'s create your first group.
📝 Tip: Recommend creating a test group first to familiarize yourself with the process
👉 Click the "Create Group" button
Give your group an easy-to-identify name.
Click "Next" when done
Choose the AI platform this group supports.
One group can only have one platform
Set the billing multiplier to control user charges.
Recommend setting test group to 1.0
Control group visibility and access permissions.
💡 Use Cases: VIP exclusive, internal testing, special customers
Confirm the information and click create to save the group.
⚠️ Note: Platform type cannot be changed after creation, but other settings can be edited anytime
📌 Next Step: After creation, we\'ll add upstream accounts to this group
👉 Click "Create" button
Great! Group created successfully 🎉
Now add upstream AI service accounts to enable actual service delivery.
👉 Click "Account Management" on the left sidebar
Click the button to start adding your first upstream account.
💡 Tip: Recommend using OAuth method - more secure and no manual key extraction needed
👉 Click "Add Account" button
Set an easy-to-identify name for the account.
💡 Naming Suggestions: "Claude Main", "GPT Backup 1", "Test Account", etc.
Choose the service provider platform for this account.
⚠️ Important: Platform must match the group you just created
Choose the account authorization method.
Set the account call priority.
💡 Use Case: Set main account to high priority, backup accounts to low priority
Key Step! Assign the account to the group you just created.
💡 Tip: Select the test group you just created
Confirm the information and click save.
📌 Next Step: After adding account, we\'ll create an API key
👉 Click "Save" button
Congratulations! Account setup complete 🎉
Final step: generate an API Key to test if the service works properly.
👉 Click "API Keys" on the left sidebar
Click the button to create your first API Key.
💡 Tip: Copy and save immediately after creation - key is only shown once
👉 Click "Create Key" button
Set an easy-to-manage name for the key.
💡 Naming Suggestions: "Test Key", "Production", "Mobile", etc.
Select the group you just configured.
💡 Tip: Select the test group you just created
System will generate a complete API Key after clicking create.
👉 Click "Create" button
Hello! Welcome to the Sub2API AI service platform.
🎯 Quick Start:
Just 1 minute, let\'s get started →
Manage all your API access keys here.
📌 What is an API Key?
An API key is your credential for accessing AI services, like a key that allows your application to call AI capabilities.
👉 Click to enter key page
Click the button to create your first API key.
💡 Tip: Key is only shown once after creation, make sure to copy and save
👉 Click "Create Key"
Give your key an easy-to-identify name.
💡 Examples: "My First Key", "For Testing", etc.
Select the service group assigned by the administrator.
📌 Group Info:
Different groups may have different service quality and billing rates, choose according to your needs.
Click to confirm and create your API key.
🚀 How to Use:
Configure the key in any OpenAI-compatible client (like ChatBox, OpenCat, etc.) and start using!
👉 Click "Create" button