Get Load Balancing Statistics
November 17, 2025 (May 20, 2026)
Table of contents
Get load balancing statistics across all configured Google Flow accounts. This endpoint provides real-time visibility into job distribution, account health, and performance metrics for both image and video generation.
To retrieve a specific job, use GET /jobs/jobId.
https://api.useapi.net/v1/google-flow/jobs/?options=
options
Request Headers
Authorization: Bearer {API token}
API tokenis required, see Setup useapi.net for details.
Query Parameters
optionsis optional, controls the level of detail in the response (default:summary).
Supported values:summary: Returns aggregated stats per account (executing, completed, failed, rate limited counts)executing: Adds details of currently executing jobs with elapsed timehistory: Includes top 10 most recent completed jobs from the last 15 minutes
Load Balancing Algorithm
When you have multiple Google Flow accounts configured and don’t specify an email parameter in POST /images or POST /videos, the API automatically selects the best account in two steps: a quarantine pre-filter, then a scoring algorithm over the survivors.
Step 1 — Quarantine pre-filter
Accounts that recently hit a known recoverable Google quota or throttle are excluded from scoring entirely until their quarantine expires. This avoids retrying an account that we already know cannot succeed, and pushes load to the remaining healthy accounts.
Quarantines are recorded automatically when a generation request returns 429 with one of these reasons:
| Reason | Scope | Cleared at |
|---|---|---|
PUBLIC_ERROR_USER_QUOTA_REACHED | All models on that account | Next UTC midnight |
PUBLIC_ERROR_PER_MODEL_DAILY_QUOTA_REACHED | Only the model that failed (other models on the same account remain eligible) | Next UTC midnight |
PUBLIC_ERROR_USER_REQUESTS_THROTTLED | All models on that account | ~30 minutes after first hit |
Quarantine is idempotent: repeated 429s for the same (account, reason, model) tuple preserve the original firstSeen timestamp; only the entry’s TTL is refreshed if needed.
If every account is quarantined for the requested model, the API returns 429 with error: "no_eligible_account" and a Retry-After header indicating the earliest cooldown. See the 429 response details on the image/video endpoints: POST /images / POST /videos.
Explicit email bypasses the filter. If you specify an email parameter, the load balancer is skipped entirely — your request goes to that account even if it’s quarantined.
Step 2 — Scoring
Among the accounts that survive Step 1, the API picks the one with the lowest score:
Formula: score = executing + (failed × 10) + (rateLimited × 20)
Lower scores are better. The account with the lowest score receives the next job.
Components:
-
executing: Number of jobs currently running on this account Weight: 1× (each executing job adds 1 point) Purpose: Distribute load evenly across accounts -
failed: Number of failed jobs (non-429 4xx/5xx responses) in last 15 minutes Weight: 10× (each failure adds 10 points) Purpose: Heavily penalize unreliable accounts -
rateLimited: Number of 429 rate limit responses in last 15 minutes Weight: 20× (each rate limit adds 20 points) Purpose: Most heavily penalize rate-limited accounts to avoid hitting limits
Example scores:
- Idle account:
0 executing + 0 failed + 0 rateLimited = 0(best) - 2 jobs running:
2 executing + 0 failed + 0 rateLimited = 2 - 1 recent failure:
0 executing + 1 failed + 0 rateLimited = 10 - 1 rate limit hit:
0 executing + 0 failed + 1 rateLimited = 20 - Rate limited account:
0 executing + 0 failed + 2 rateLimited = 40(worst)
Randomization: When multiple accounts have the same score, one is selected randomly.
Stats expiration: Job statistics older than 15 minutes are automatically removed from load balancing calculations.
Responses
-
Returns load balancing statistics categorized by job type.
With
options=summary(default):{ "emails": [ "jo***@gmail.com", "an***@gmail.com" ], "videos": { "summary": { "jo***@gmail.com": { "executing": 2, "completed": 15, "failed": 0, "rateLimited": 0, "avgResponseTime": 125340.50, "score": 2 }, "an***@gmail.com": { "executing": 0, "completed": 8, "failed": 1, "rateLimited": 0, "avgResponseTime": 98234.75, "score": 10 } } }, "images": { "summary": { "jo***@gmail.com": { "executing": 1, "completed": 42, "failed": 0, "rateLimited": 0, "avgResponseTime": 12456.30, "score": 1 }, "an***@gmail.com": { "executing": 0, "completed": 38, "failed": 0, "rateLimited": 1, "avgResponseTime": 15234.80, "score": 20 } } }, "combined": { "summary": { "jo***@gmail.com": { "executing": 3, "completed": 57, "failed": 0, "rateLimited": 0, "avgResponseTime": 32145.60, "score": 3 }, "an***@gmail.com": { "executing": 0, "completed": 46, "failed": 1, "rateLimited": 1, "avgResponseTime": 42367.25, "score": 30 } } } }With
options=executing:Adds
executingobject with currently running jobs and their elapsed time inMM:SSformat:{ "emails": [ "jo***@gmail.com", "an***@gmail.com" ], "videos": { "summary": { "..." }, "executing": { "j1731...redacted...v-u12345-email:jo***@gmail.com-bot:google-flow": { "email": "jo***@gmail.com", "timestamp": 1731859234567, "elapsed": "1:23" }, "j1731...redacted...v-u12345-email:jo***@gmail.com-bot:google-flow-http:200": { "email": "jo***@gmail.com", "timestamp": 1731859123456, "elapsed": "3:45" } } }, "images": { "summary": { "..." }, "executing": { "j1731...redacted...i-u12345-email:jo***@gmail.com-bot:google-flow": { "email": "jo***@gmail.com", "timestamp": 1731859345678, "elapsed": "0:15" } } }, "combined": { "summary": { "..." } } }With
options=history:Adds both
executingandhistoryobjects with top 10 most recent completed jobs from last 15 minutes:{ "emails": [ "jo***@gmail.com", "an***@gmail.com" ], "videos": { "summary": { "..." }, "executing": { "..." }, "history": { "j1731...redacted...v-u12345-email:jo***@gmail.com-bot:google-flow": { "email": "jo***@gmail.com", "timestamp": 1731858123456, "httpStatus": 200, "responseTime": 125340 }, "j1731...redacted...v-u12345-email:an***@gmail.com-bot:google-flow": { "email": "an***@gmail.com", "timestamp": 1731858234567, "httpStatus": 500, "responseTime": 98234 } } }, "images": { "summary": { "..." }, "executing": { "..." }, "history": { "..." } }, "combined": { "summary": { "..." } } } -
Invalid API token.
{ "error": "Unauthorized" } -
Invalid
optionsparameter value.{ "error": "Invalid options parameter. Use: summary, executing, or history" }
Model
{
emails: string[] // List of all configured healthy account emails
videos: {
summary: {
[email: string]: {
executing: number // Currently running jobs
completed: number // Successfully completed (2xx) in last 15min
failed: number // Failed (4xx/5xx except 429) in last 15min
rateLimited: number // Rate limited (429) in last 15min
avgResponseTime: number // Average response time in milliseconds
score: number // Load balancing score (lower is better)
}
}
executing?: { // Only with options=executing or history
[jobId: string]: {
email: string // Account email
timestamp: number // Unix timestamp (milliseconds)
elapsed: string // Elapsed time in MM:SS format
}
}
history?: { // Only with options=history
[jobId: string]: {
email: string // Account email
timestamp: number // Unix timestamp (milliseconds)
httpStatus: number // HTTP status code (200, 429, 500, etc.)
responseTime: number // Response time in milliseconds
}
}
}
images: {
summary: {
[email: string]: {
executing: number // Currently running jobs
completed: number // Successfully completed (2xx) in last 15min
failed: number // Failed (4xx/5xx except 429) in last 15min
rateLimited: number // Rate limited (429) in last 15min
avgResponseTime: number // Average response time in milliseconds
score: number // Load balancing score (lower is better)
}
}
executing?: { // Only with options=executing or history
[jobId: string]: {
email: string // Account email
timestamp: number // Unix timestamp (milliseconds)
elapsed: string // Elapsed time in MM:SS format
}
}
history?: { // Only with options=history
[jobId: string]: {
email: string // Account email
timestamp: number // Unix timestamp (milliseconds)
httpStatus: number // HTTP status code (200, 429, 500, etc.)
responseTime: number // Response time in milliseconds
}
}
}
combined: {
summary: {
[email: string]: {
executing: number // Currently running jobs
completed: number // Successfully completed (2xx) in last 15min
failed: number // Failed (4xx/5xx except 429) in last 15min
rateLimited: number // Rate limited (429) in last 15min
avgResponseTime: number // Average response time in milliseconds
score: number // Load balancing score (lower is better)
}
}
}
}
Examples
-
# Get summary stats (default) curl "https://api.useapi.net/v1/google-flow/jobs" \ -H "Authorization: Bearer {API token}" # Get executing jobs with elapsed time curl "https://api.useapi.net/v1/google-flow/jobs/?options=executing" \ -H "Authorization: Bearer {API token}" # Get full history (last 15 minutes) curl "https://api.useapi.net/v1/google-flow/jobs/?options=history" \ -H "Authorization: Bearer {API token}" -
const apiToken = 'your-api-token' // Get summary stats (default) const response = await fetch('https://api.useapi.net/v1/google-flow/jobs', { headers: { 'Authorization': `Bearer ${apiToken}` } }) const stats = await response.json() // Check which account has lowest score for images const imagesSummary = stats.images.summary const bestAccount = Object.entries(imagesSummary) .sort(([, a], [, b]) => a.score - b.score)[0] console.log('Best account for images:', bestAccount[0], 'score:', bestAccount[1].score) // Get executing jobs const execResponse = await fetch('https://api.useapi.net/v1/google-flow/jobs/?options=executing', { headers: { 'Authorization': `Bearer ${apiToken}` } }) const execStats = await execResponse.json() console.log('Currently executing videos:', Object.keys(execStats.videos.executing || {}).length) -
import requests api_token = 'your-api-token' headers = {'Authorization': f'Bearer {api_token}'} # Get summary stats (default) response = requests.get( 'https://api.useapi.net/v1/google-flow/jobs', headers=headers ) stats = response.json() # Check which account has lowest score for videos videos_summary = stats['videos']['summary'] best_account = min(videos_summary.items(), key=lambda x: x[1]['score']) print(f"Best account for videos: {best_account[0]}, score: {best_account[1]['score']}") # Get full history history_response = requests.get( 'https://api.useapi.net/v1/google-flow/jobs/?options=history', headers=headers ) history_stats = history_response.json() print(f"Image job history entries: {len(history_stats['images'].get('history', {}))}")