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/credits

Returns 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"
}
FieldTypeDescription
available_centsintegerCredits available for new jobs
held_centsintegerCredits held in escrow for active jobs
total_centsintegeravailable_cents + held_cents
currencystringAlways usd

List Transactions

GET /v1/billing/transactions

Returns credit transaction history (purchases, deductions, bonuses, free tier grants, refunds, expirations).

Query Parameters:

ParamTypeDescription
typestringFilter: purchase, deduction, free_tier, bonus, expiration, refund
limitintegerMax results (1-100, default 20)
cursorstringPagination 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/purchase

Initiates 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:

FieldTypeRequiredDescription
amount_centsintegeryesPurchase 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:

RecipientShare
Worker80% of price per file
FirstHandAPI20% of price per file

There are no additional platform fees. You pay only for approved files.

Credit Packs

Larger purchases include bonus credits:

PurchaseBase CreditsBonusTotal
$101,0001,000
$252,500+5%2,625
$505,000+10%5,500
$10010,000+15%11,500
$25025,000+20%30,000

Credits expire 12 months after purchase. See Credit Billing guide for details.