Billing
FirstHandAPI uses a pre-funded credit model. Credits are consumed when submissions are approved. See the Credit Billing guide for the full escrow model and pricing details.
Get Credit Balance
GET /v1/billing/creditsReturns current credit balance and pending holds.
curl https://api.firsthandapi.com/v1/billing/credits \
-H "Authorization: Bearer fh_live_..."const balance = await client.getCreditBalance();
console.log(`Available: $${(balance.available_cents / 100).toFixed(2)}`);balance = client.get_credit_balance()
print(f"Available: ${balance['available_cents'] / 100:.2f}")Response: 200 OK
{
"object": "credit_balance",
"available_cents": 45000,
"held_cents": 5000,
"total_cents": 50000,
"currency": "usd",
"updated_at": "2026-03-21T10:30:00Z"
}| Field | Type | Description |
|---|---|---|
available_cents | integer | Credits available for new jobs |
held_cents | integer | Credits held in escrow for active jobs |
total_cents | integer | available_cents + held_cents |
currency | string | Always usd |
List Transactions
GET /v1/billing/transactionsReturns credit transaction history (purchases, deductions, bonuses, free tier grants, refunds, expirations).
Query Parameters:
| Param | Type | Description |
|---|---|---|
type | string | Filter: purchase, deduction, free_tier, bonus, expiration, refund |
limit | integer | Max results (1-100, default 20) |
cursor | string | Pagination cursor |
curl "https://api.firsthandapi.com/v1/billing/transactions?limit=5" \
-H "Authorization: Bearer fh_live_..."const txns = await client.listTransactions({ limit: 5 });
for (const txn of txns.data) {
console.log(`${txn.type}: ${txn.amount_cents}c — ${txn.description}`);
}txns = client.list_transactions(limit=5)
for txn in txns["data"]:
print(f"{txn['type']}: {txn['amount_cents']}c — {txn['description']}")Response: 200 OK
{
"object": "list",
"data": [
{
"object": "credit_transaction",
"id": "crtx_01JQ...",
"type": "purchase",
"amount_cents": 11500,
"description": "$100 credit pack (+15% bonus)",
"created_at": "2026-03-20T14:00:00Z"
},
{
"object": "credit_transaction",
"id": "crtx_01JR...",
"type": "deduction",
"amount_cents": -50,
"description": "File approved for job_01JQ...",
"job_id": "job_01JQ...",
"submission_id": "sub_01JQ...",
"created_at": "2026-03-21T09:15:00Z"
},
{
"object": "credit_transaction",
"id": "crtx_01JS...",
"type": "refund",
"amount_cents": 1350,
"description": "Job cancelled — unused escrow refunded",
"job_id": "job_01JQ...",
"created_at": "2026-03-21T10:00:00Z"
}
],
"has_more": true,
"next_cursor": "crtx_01JS..."
}Purchase Credits
POST /v1/billing/credits/purchaseInitiates a credit purchase via Stripe Checkout. Returns a URL to redirect the user.
Headers:
Authorization: Bearer fh_live_...(required)Idempotency-Key: <unique-key>(required)Content-Type: application/json
Request Body:
| Field | Type | Required | Description |
|---|---|---|---|
amount_cents | integer | yes | Purchase amount in cents (min: 1000, max: 100000) |
curl -X POST https://api.firsthandapi.com/v1/billing/credits/purchase \
-H "Authorization: Bearer fh_live_..." \
-H "Idempotency-Key: purchase-001" \
-H "Content-Type: application/json" \
-d '{"amount_cents": 10000}'const purchase = await client.purchaseCredits({ amount_cents: 10000 });
// Redirect user to purchase.checkout_url
console.log(purchase.checkout_url);purchase = client.purchase_credits({"amount_cents": 10000})
# Redirect user to purchase["checkout_url"]
print(purchase["checkout_url"])Response: 200 OK
{
"object": "checkout_session",
"checkout_url": "https://checkout.stripe.com/c/pay/cs_live_...",
"amount_cents": 10000,
"bonus_cents": 1500,
"total_credits_cents": 11500,
"expires_at": "2026-03-21T11:30:00Z"
}Credits are applied to your account after Stripe confirms payment via webhook (typically within seconds). Use the credits.purchased webhook event to get notified.
Pricing
Buyers set the price per file when creating a job. The platform split is:
| Recipient | Share |
|---|---|
| Worker | 80% of price per file |
| FirstHandAPI | 20% of price per file |
There are no additional platform fees. You pay only for approved files.
Credit Packs
Larger purchases include bonus credits:
| Purchase | Base Credits | Bonus | Total |
|---|---|---|---|
| $10 | 1,000 | — | 1,000 |
| $25 | 2,500 | +5% | 2,625 |
| $50 | 5,000 | +10% | 5,500 |
| $100 | 10,000 | +15% | 11,500 |
| $250 | 25,000 | +20% | 30,000 |
Credits expire 12 months after purchase. See Credit Billing guide for details.