Skip to main content

API reference

Wallet

Balance and transactions.

Beta. This endpoint is not final. Field names and response shapes can change before general availability.

Overview

Every Finn workspace has one wallet. Calls, phone number rent, and other usage draw down the wallet balance. When the balance reaches zero, outbound campaigns stop dispatching and inbound calls are rejected before they are answered, so treat the balance as an operational signal, not an accounting detail.

The Wallet API is read-only in beta. You can read the current balance and page through the transactions that produced it. Topping up is done in the dashboard, not through the API. There is no API method for adding funds, and none is planned for the first release.

Base URL is https://api.hirefinn.ai/v1. All requests need Authorization: Bearer <FINN_API_KEY>. See authentication and api-conventions.

Get the wallet

curl https://api.hirefinn.ai/v1/wallet \
  -H "Authorization: Bearer $FINN_API_KEY"
{
  "object": "wallet",
  "id": "wal_8f3a21c9",
  "balance": 42350,
  "currency": "USD",
  "updated_at": "2026-07-30T09:14:02Z"
}
FieldTypeNotes
idstringWallet identifier. One wallet per workspace.
balanceintegerBalance in the smallest currency unit. 42350 with currency: "USD" means 423.50 USD.
currencystringISO 4217 code. Fixed at workspace creation and not changeable through the API.
updated_atstringRFC 3339 timestamp of the last balance change.

Read balance as a minor-unit integer. If you render it as a float without dividing by 100, you will show a balance a hundred times too large, and this is the most common integration mistake with this endpoint.

Whether the response also carries a low-balance threshold or an auto-recharge object is not yet settled. Do not depend on fields beyond the four above.

List transactions

curl "https://api.hirefinn.ai/v1/wallet/transactions?limit=20" \
  -H "Authorization: Bearer $FINN_API_KEY"
{
  "object": "list",
  "data": [
    {
      "object": "wallet_transaction",
      "id": "wtx_5c1d90ab",
      "type": "call_usage",
      "amount": -1840,
      "currency": "USD",
      "balance_after": 42350,
      "description": "Outbound call, 4m 12s",
      "call_id": "call_71b0e4f2",
      "created_at": "2026-07-30T09:14:02Z"
    },
    {
      "object": "wallet_transaction",
      "id": "wtx_44ae02f1",
      "type": "topup",
      "amount": 50000,
      "currency": "USD",
      "balance_after": 44190,
      "description": "Card top-up",
      "call_id": null,
      "created_at": "2026-07-29T17:02:44Z"
    }
  ],
  "has_more": true,
  "next_cursor": "wtx_44ae02f1"
}

amount is signed. Debits are negative, credits are positive. balance_after is the wallet balance immediately after the transaction was applied, which lets you reconcile a page without replaying the whole ledger.

FieldTypeNotes
idstringTransaction identifier.
typestringSee the table below.
amountintegerSigned minor units. Negative for debits.
balance_afterintegerBalance after this entry.
descriptionstringHuman-readable label. Free text. Do not parse it.
call_idstring or nullSet for call-derived entries. Null otherwise. Join against api-calls.
created_atstringRFC 3339 timestamp.

Transaction types

typeSignMeaning
call_usagenegativeCharge for a completed call.
number_rentnegativeRecurring charge for a rented phone number. See api-phone-numbers.
topuppositiveFunds added from the dashboard.
adjustmenteitherManual correction applied by Finn support.
refundpositiveReversal of an earlier charge.

Treat this list as open. New types can be added without a version bump, so route unknown values to a default branch rather than throwing.

Query parameters

ParameterTypeDefaultNotes
limitinteger20Page size.
cursorstringnoneCursor from next_cursor.
typestringnoneFilter to one transaction type.
created_afterstringnoneRFC 3339. Inclusive.
created_beforestringnoneRFC 3339. Exclusive.

Pagination follows api-pagination. Order is newest first. A call charge lands after the call ends, not while it is in progress, so a transaction list read seconds after a call completes may not include it yet.

Poll the balance

import os
import requests

BASE = "https://api.hirefinn.ai/v1"
HEADERS = {"Authorization": f"Bearer {os.environ['FINN_API_KEY']}"}

def balance_minor_units() -> int:
    r = requests.get(f"{BASE}/wallet", headers=HEADERS, timeout=10)
    r.raise_for_status()
    return r.json()["balance"]

def low(threshold_major: float = 100.0) -> bool:
    return balance_minor_units() < threshold_major * 100

if low():
    print("Wallet below 100.00. Top up before the next campaign.")

Poll on a schedule rather than before each call. The endpoint counts against your api-rate-limits budget, and a balance read in a per-call hot path is the first thing to hit the limit during a campaign.

Whether Finn emits a webhook on low balance is not yet settled. Until it is documented in webhook-events, polling is the only supported mechanism.

Errors

StatusCondition
401Missing or invalid API key.
403Key lacks wallet read scope.
404No wallet provisioned for the workspace.
429Rate limited. Back off and retry.

Error bodies follow api-errors. A 404 here usually means the workspace was created but never completed billing setup, not that the wallet was deleted.