Vinci uses a simple usage-based model. This guide shows how to query your balance and usage, add a quick balance guard before costly requests, and handle 402 errors. Related:

Check balance

Endpoint
GET /api/v1/billing/balance
Authentication
Authorization: Bearer sk-your-api-key-here
Response
{
  "balance_usd": 25.50,
  "total_spent_usd": 134.75
}
curl -X GET "https://tryvinci.com/api/v1/billing/balance" \
  -H "Authorization: Bearer sk-your-api-key-here"

Usage statistics

Endpoint
GET /api/v1/billing/usage?days={days}
Authentication
Authorization: Bearer sk-your-api-key-here
Response
{
  "period_days": 30,
  "total_requests": 156,
  "total_seconds": 420.5,
  "total_cost_usd": 21.025,
  "current_balance_usd": 25.50,
  "total_spent_usd": 134.75
}
curl -X GET "https://tryvinci.com/api/v1/billing/usage?days=7" \
  -H "Authorization: Bearer sk-your-api-key-here"

Balance check helper

import requests

def has_sufficient_balance(duration_seconds, api_key):
    balance_url = "https://tryvinci.com/api/v1/billing/balance"
    headers = {"Authorization": f"Bearer {api_key}"}
    r = requests.get(balance_url, headers=headers)
    r.raise_for_status()
    balance = r.json()
    estimated = duration_seconds * 0.05
    return balance["balance_usd"] >= estimated
Related

Handle insufficient balance (402)

Example 402 response
{
  "detail": "Insufficient balance. Current balance: $1.25, required: $2.50"
}
handle_402.py
import requests

def request_video(prompt, duration, api_key):
    url = "https://tryvinci.com/api/v1/generate/text-to-video"
    headers = {"Authorization": f"Bearer {api_key}", "Content-Type": "application/json"}
    data = {"prompt": prompt, "duration_seconds": duration}
    r = requests.post(url, headers=headers, json=data)
    if r.status_code == 402:
        print(f"Insufficient balance: {r.json().get('detail')}")
        return None
    r.raise_for_status()
    return r.json()
handle_402.js
async function requestVideo(prompt, duration, apiKey) {
  const url = "https://tryvinci.com/api/v1/generate/text-to-video";
  const r = await fetch(url, {
    method: "POST",
    headers: {
      "Authorization": `Bearer ${apiKey}`,
      "Content-Type": "application/json",
    },
    body: JSON.stringify({ prompt, duration_seconds: duration }),
  });
  if (r.status === 402) {
    const err = await r.json();
    console.log(`Insufficient balance: ${err.detail}`);
    return null;
  }
  if (!r.ok) throw new Error(`HTTP ${r.status}`);
  return await r.json();
}
Info For production, add retry with exponential backoff and alerts when balance falls below a threshold.