Skip to main content
The company balance flips the default user funded model: your company prefunds one pooled balance, and when a connected user’s agent creates a card, Agentcard moves exactly that card’s amount from your pool into the user’s spending power. Your users never see a funding step, and you stay in the transaction loop to collect from your own customer first.
The flow of funds is chosen when you create the company (user funded or company balance). A company owner can switch models from the dashboard’s Company balance page, but only until the company first moves money (a card is funded, a transfer runs, or a deposit lands); after that the choice locks. Companies on the company balance model get the full test-mode loop immediately and free; live usage (the real pool, real transfers) requires an active paid subscription, the same one that unlocks production clients.

The flow of funds

Company balance flow of funds diagram

Company balance: from create_card to the agent paying the merchant

Step by step, for one card:
  1. A connected user’s agent calls create_card with the company flow. Agentcard checks your pool covers the amount (plus fees) and reserves it.
  2. You receive a card_flow.started webhook. This is your moment to collect: place a hold on your customer’s payment method in your own billing system.
  3. You report the outcome with the confirm_collection tool — outcome succeeded, or failed to release the reservation.
  4. Agentcard transfers the amount from your balance into the user’s spending power (about 30 seconds on-chain) and emits transfer.initiated, then transfer.completed.
  5. Capture your customer’s payment when you receive transfer.completed. From this point the funding is final: even if the card mint failed afterward, the money stays as that user’s spending power and automatically offsets their next card (you would see card_flow.failed with funds_status: released_to_headroom).
  6. The card mints and card.created fires with the transfer_id, then the agent pays the merchant as usual.
  7. If the card closes with unused balance, transfer.released fires so you can release or refund your own hold. The unused amount stays as that user’s spending power and reduces what your pool sends on their next card.
Companies that prefer not to confirm each funding can set ack_mode: auto_approve (dashboard or CLI): step 2 still fires as a webhook, but the transfer proceeds without waiting.

Fund the balance

Set up the balance once (dashboard: Company balance → Set up balance, or agent-cards companies balance provision --org <org-id>). Then fund it two ways — both credit the same pool and fire the same wallet.funded webhook:
  • Apple Pay / Google Pay (dashboard → Company balance → Add funds, admins only). A hosted card checkout — no crypto wallet needed. Any debit or credit card inside Apple/Google Pay works (a Mercury card, for example). First use verifies a US phone with a one-time code, and the payment provider may run a quick identity check on the payer the first time. 2020–10,000 per transaction; no lifetime purchase caps. Agentcard covers the provider fee (up to a cap), so the full amount lands.
  • USDC on Base — send to the pool’s deposit address. No caps; this is the rail for recurring, treasury-scale funding.
Deposits are detected automatically. Set a low-balance threshold to get wallet.balance.low before a card creation ever fails for insufficient funds. Creating the live pool and funding it both require the active subscription; without one these calls return 403 subscription_required (test credentials and the mock pool keep working). Subscribe from the dashboard’s Go live page.

The create_card protocol

The end user’s agent calls the same create_card it always has. Two additions:
  • An optional funds_source (onramp_flow or company_flow). Most companies set their default funds source to company_flow so agents never pass it.
  • While funding is in flight, create_card returns 202 { "status": "funding_in_progress", "transferId": "owt_…", "retry_after_seconds": 10 }. The agent retries with the same arguments and attaches to the in-flight funding, returning the card when it is ready. A retry that lands after the mint still returns that card (for about 2 minutes, while it is unused) instead of opening a second funding. Declined or timed-out collections surface as 422 funding_not_approved.
Server-initiated issuance works too: your backend can call create_card itself with funds_source: "company_flow". Your own call counts as the collection confirmation, and passing an idempotency_key makes retries attach instead of double-funding. Reusing a key with a different amount or cardholder is rejected with 409 idempotency_key_reuse; use a fresh key for each new request.

Balance tools

Available with your company credentials: Transfers move through public states pending (substates: awaiting_collection, collection_confirmed, transferring), funded, consumed, reclaimed, and failed (with a failure_reason).

Try it in test mode

The whole loop runs in test mode with no real money: fund the mock pool from the dashboard’s Company balance page (test mode), then run create_card with a test credential. The same webhooks fire with livemode: false, the transfer simulates in about 2 seconds, and the card is a mock. Integrate the webhook and collection confirmation exactly as you would in production.

Events