Credit Billing
FirstHandAPI uses a pre-funded credit model. Purchase credits upfront, and they are consumed as worker submissions are approved.
How Credits Work
- Purchase credits via Stripe Checkout
- Credits are held when a job is posted (files_needed x price_per_file)
- Credits are deducted when submissions are approved (worker gets 80%, platform gets 20%)
- Remaining held credits are released when a job completes or is cancelled
Credit Packs
Larger packs include bonus credits:
| Pack | Price | Base Credits | Bonus | Total Credits |
|---|---|---|---|---|
| $10 | $10 | 1,000 | — | 1,000 |
| $25 | $25 | 2,500 | +5% | 2,625 |
| $50 | $50 | 5,000 | +10% | 5,500 |
| $100 | $100 | 10,000 | +15% | 11,500 |
| $250 | $250 | 25,000 | +20% | 30,000 |
Credits expire 12 months from the date of purchase.
Checking Your Balance
curl https://api.firsthandapi.com/v1/billing/credits \
-H "Authorization: Bearer fh_live_..."{
"balance_cents": 45000,
"currency": "usd",
"updated_at": "2026-03-21T10:30:00Z"
}const balance = await client.getCreditBalance();
console.log(balance.balance_cents); // 45000 ($450.00)Purchasing Credits
const purchase = await client.purchaseCredits({
amount_cents: 10000, // $100.00
});
// Redirect user to purchase.checkout_urlpurchase = client.purchase_credits({"amount_cents": 10000})
# Redirect user to purchase["checkout_url"]Cost Per File
You set the price per file when creating a job. The platform split is:
| Recipient | Share |
|---|---|
| Worker | 80% |
| FirstHandAPI | 20% |
Example: If you set price_per_file_cents: 100 ($1.00), the worker receives $0.80 and the platform takes $0.20.
Escrow Model
When you create a job, credits are escrowed (held) to guarantee payment to workers:
Escrow = files_needed × price_per_file_centsExample: A job requesting 100 photos at $0.50 each holds $50.00 in escrow.
- On file approval: escrowed credits are released to the worker (80%) and platform (20%)
- On job cancel: unused escrowed credits are returned to your available balance immediately
- On job completion: any remaining escrow (if fewer files approved than requested) is released back
You are never charged for rejected submissions. Only approved files consume credits.
Auto-Rejections (No Credit Cost)
Several automatic checks reject submissions before AI scoring runs — these consume zero credits:
| Check | Trigger | Cost |
|---|---|---|
| Resolution check | Image/video below job’s min_width or min_height | Free |
| Stock photo detection | Reverse image search matches known stock libraries | Free |
| Format mismatch | File bytes don’t match declared MIME type | Free |
AI-scored rejections (1-2 star scores) also don’t consume credits. Credits are only consumed when a submission is approved (3+ stars).
Insufficient Credits
If you don’t have enough credits to cover the escrow, the API returns 402:
{
"error": {
"type": "insufficient_credits",
"current_balance_cents": 200,
"required_cents": 5000,
"shortfall_cents": 4800,
"affordable_files": 4,
"purchase_url": "https://dashboard.firsthandapi.com/billing"
}
}Transaction History
curl "https://api.firsthandapi.com/v1/billing/transactions?limit=20" \
-H "Authorization: Bearer fh_live_..."Credit Expiration
Credits expire 12 months after purchase. Expiring credits are consumed first (FIFO). You’ll receive a credits.expiring_soon webhook event 30 days before expiration and a credits.expired event when credits expire.
Purchased credits do not expire while held in escrow for active jobs.
Zero-Balance Behavior
When your credit balance reaches zero:
- Active jobs continue — Workers can still submit to in-progress jobs as long as escrow covers the remaining files
- New job creation blocked —
POST /v1/jobsreturns402 insufficient_creditswith your current balance and the required amount - No automatic cancellation — Existing jobs are never cancelled due to low balance
- Low balance alert — You receive a
credits.low_balancewebhook event when your available balance drops below 10% of your total escrow