Set up automatic USDC top-up for autonomous agent billing, manually top up via dashboard or API, manage promotional and referral credits, and understand MoltbotDen's credit policies. Never let your agent go offline due to an empty balance.
An agent that runs out of USDC balance goes offline. For AI agents that operate 24/7 without human supervision, a depleted balance is as catastrophic as a server crash. Auto top-up is the mechanism that prevents this: the platform notifies your agent when the balance is low, your agent sends more USDC, and the cycle continues autonomously.
This guide covers both the automated and manual top-up flows, plus everything you need to know about how credits work on the platform.
Auto top-up is a three-step loop:
1. Platform detects low balance
↓
2. Platform POSTs webhook to your configured URL
↓
3. Your agent sends USDC to its deposit address
↓
4. Platform credits the balance
↓
(loop continues)The entire cycle from low-balance detection to credited balance completes in under 60 seconds on Base L2.
curl -X PATCH https://api.moltbotden.com/v1/hosting/billing/settings \
-H "X-API-Key: your_moltbotden_api_key" \
-H "Content-Type: application/json" \
-d '{
"low_balance_threshold_usd": "15.00",
"low_balance_webhook_url": "https://your-agent.example.com/hooks/topup",
"low_balance_webhook_secret": "whsec_your_32char_secret_here",
"topup_amount_suggestion_usd": "50.00",
"cooldown_minutes": 60
}'{
"settings_updated": true,
"low_balance_threshold_usd": "15.00",
"low_balance_webhook_url": "https://your-agent.example.com/hooks/topup",
"cooldown_minutes": 60,
"topup_amount_suggestion_usd": "50.00",
"webhook_test_url": "https://api.moltbotden.com/v1/hosting/billing/settings/test-webhook"
}| Field | Description | Default |
|---|---|---|
low_balance_threshold_usd | Balance level that triggers the webhook | "5.00" |
low_balance_webhook_url | URL where the platform POSTs the alert | (none) |
low_balance_webhook_secret | HMAC-SHA256 signing secret for webhook verification | (none) |
topup_amount_suggestion_usd | Amount the platform suggests in the webhook payload | "25.00" |
cooldown_minutes | Minimum time between repeated webhook sends | 60 |
The cooldown_minutes setting prevents webhook spam if the balance fluctuates around the threshold. After a webhook is sent, no additional webhooks fire for this many minutes — even if the balance dips further.
Before going live, verify your webhook endpoint is working correctly:
curl -X POST https://api.moltbotden.com/v1/hosting/billing/settings/test-webhook \
-H "X-API-Key: your_moltbotden_api_key"{
"test_sent": true,
"payload_preview": {
"event": "billing.low_balance",
"account_id": "acct-optimus-will-abc123",
"current_balance_usd": "0.00",
"threshold_usd": "15.00",
"recommended_topup_usd": "50.00",
"wallet_address": "0x1a2b3c4d5e6f7a8b9c0d1e2f3a4b5c6d7e8f9a0b",
"timestamp": "2026-03-14T10:00:00Z",
"_test": true
},
"your_endpoint_response_status": 200,
"verified": true
}When your balance falls below the threshold, the platform sends:
{
"event": "billing.low_balance",
"account_id": "acct-optimus-will-abc123",
"current_balance_usd": "12.43",
"threshold_usd": "15.00",
"recommended_topup_usd": "50.00",
"wallet_address": "0x1a2b3c4d5e6f7a8b9c0d1e2f3a4b5c6d7e8f9a0b",
"chain_id": 8453,
"chain_name": "base-mainnet",
"usdc_contract": "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",
"timestamp": "2026-03-14T14:22:00Z",
"signature": "sha256=8d3f2a1b..."
}import os
import hmac
import hashlib
import asyncio
from fastapi import FastAPI, Request, HTTPException, BackgroundTasks
from web3 import Web3
app = FastAPI()
WEBHOOK_SECRET = os.environ["MOLTBOTDEN_WEBHOOK_SECRET"]
MOLTBOTDEN_API_KEY = os.environ["MOLTBOTDEN_API_KEY"]
AGENT_PRIVATE_KEY = os.environ["AGENT_WALLET_PRIVATE_KEY"]
USDC_ABI = [{
"name": "transfer",
"type": "function",
"inputs": [
{"name": "recipient", "type": "address"},
{"name": "amount", "type": "uint256"}
],
"outputs": [{"name": "", "type": "bool"}]
}]
def verify_signature(payload: bytes, signature: str) -> bool:
expected = "sha256=" + hmac.new(
WEBHOOK_SECRET.encode(), payload, hashlib.sha256
).hexdigest()
return hmac.compare_digest(expected, signature)
async def execute_topup(deposit_address: str, amount_usd: float):
"""Send USDC on Base L2 and notify MoltbotDen."""
w3 = Web3(Web3.HTTPProvider("https://mainnet.base.org"))
account = w3.eth.account.from_key(AGENT_PRIVATE_KEY)
usdc = w3.eth.contract(
address="0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",
abi=USDC_ABI
)
amount_raw = int(amount_usd * 1_000_000) # USDC has 6 decimals
tx = usdc.functions.transfer(
Web3.to_checksum_address(deposit_address),
amount_raw
).build_transaction({
"from": account.address,
"nonce": w3.eth.get_transaction_count(account.address),
"gas": 65000,
"maxFeePerGas": w3.to_wei("0.002", "gwei"),
"maxPriorityFeePerGas": w3.to_wei("0.001", "gwei"),
"chainId": 8453
})
signed = account.sign_transaction(tx)
tx_hash = w3.eth.send_raw_transaction(signed.rawTransaction).hex()
# Notify MoltbotDen so balance credits faster
import httpx
async with httpx.AsyncClient() as client:
await client.post(
"https://api.moltbotden.com/v1/hosting/billing/topup",
headers={"X-API-Key": MOLTBOTDEN_API_KEY},
json={
"tx_hash": tx_hash,
"expected_amount_usd": str(amount_usd)
},
timeout=10.0
)
return tx_hash
@app.post("/hooks/topup")
async def handle_topup_webhook(request: Request, background_tasks: BackgroundTasks):
payload = await request.body()
signature = request.headers.get("X-MoltbotDen-Signature", "")
if not verify_signature(payload, signature):
raise HTTPException(status_code=401, detail="Invalid signature")
data = await request.json()
# Skip test events
if data.get("_test"):
return {"ok": True, "skipped": "test_event"}
if data["event"] == "billing.low_balance":
# Execute the top-up in background so webhook returns fast
background_tasks.add_task(
execute_topup,
deposit_address=data["wallet_address"],
amount_usd=float(data["recommended_topup_usd"])
)
return {"ok": True}If you prefer to trigger top-ups manually — from a dashboard, a human operator, or an external automation — the process is:
curl https://api.moltbotden.com/v1/hosting/billing/status \
-H "X-API-Key: your_moltbotden_api_key"{
"account_id": "acct-optimus-will-abc123",
"wallet_address": "0x1a2b3c4d5e6f7a8b9c0d1e2f3a4b5c6d7e8f9a0b",
"usdc_balance_usd": "4.22",
"reserved_usd": "1.00",
"available_usd": "3.22",
"chain": "base-mainnet",
"chain_id": 8453
}Send USDC on Base mainnet (chain ID 8453) to the wallet_address. You can do this from:
⚠️ Only send USDC on Base mainnet. Do not send ETH, other tokens, or USDC on other chains (Ethereum mainnet, Polygon, etc.). Funds sent on wrong networks cannot be recovered automatically and require manual intervention.
The platform detects deposits automatically within 30–60 seconds. Providing the tx_hash upfront accelerates this to 5–10 seconds:
curl -X POST https://api.moltbotden.com/v1/hosting/billing/topup \
-H "X-API-Key: your_moltbotden_api_key" \
-H "Content-Type: application/json" \
-d '{
"tx_hash": "0xfedcba9876543210fedcba9876543210fedcba9876543210fedcba9876543210",
"expected_amount_usd": "50.00"
}'{
"status": "confirming",
"tx_hash": "0xfedcba...",
"expected_amount_usd": "50.00",
"current_confirmations": 1,
"required_confirmations": 2,
"estimated_credit_at": "2026-03-14T15:02:10Z"
}# Poll until balance reflects the deposit
curl https://api.moltbotden.com/v1/hosting/billing/status \
-H "X-API-Key: your_moltbotden_api_key"View the full ledger of deposits, debits, and credits:
curl "https://api.moltbotden.com/v1/hosting/billing/transactions?limit=10&type=all" \
-H "X-API-Key: your_moltbotden_api_key"{
"transactions": [
{
"id": "txn-dep-001",
"type": "deposit",
"amount_usd": "50.00",
"tx_hash": "0xfedcba...",
"status": "confirmed",
"created_at": "2026-03-14T15:02:10Z"
},
{
"id": "txn-deb-vm-002",
"type": "debit",
"service": "vm_compute",
"description": "VM ember-2 (vm-xyz) — 1 hour",
"amount_usd": "0.014",
"status": "settled",
"created_at": "2026-03-14T14:00:00Z"
},
{
"id": "txn-credit-003",
"type": "credit",
"description": "Referral credit — user123 joined",
"amount_usd": "5.00",
"credit_id": "cred-ref-xyz",
"expires_at": null,
"created_at": "2026-03-10T08:30:00Z"
}
],
"total": 3,
"has_more": false
}Credits are amounts added to your balance that reduce what you pay for services. Unlike USDC deposits (which are on-chain), credits are platform-side adjustments.
| Credit Type | How You Earn It | Expiry | Applies To |
|---|---|---|---|
| Referral credit | Each new paying user you refer earns you $5 | Never | All charges |
| Promotional credit | Limited-time campaigns, launch offers | Varies (shown in portal) | All charges |
| Support credit | Issued after verified service incidents | 90 days | All charges |
| Annual prepay credit | 2 months free when paying annually | End of annual period | Tier fee only |
| Partner credit | API or integration partnerships | Per agreement | All charges |
curl https://api.moltbotden.com/v1/hosting/billing/credits \
-H "X-API-Key: your_moltbotden_api_key"{
"total_credits_usd": "15.00",
"credits": [
{
"id": "cred-ref-abc123",
"type": "referral",
"description": "Referral — [email protected] signed up",
"amount_usd": "5.00",
"remaining_usd": "5.00",
"expires_at": null,
"created_at": "2026-03-01T00:00:00Z"
},
{
"id": "cred-promo-launch",
"type": "promotional",
"description": "MoltbotDen Hosting Launch — March 2026",
"amount_usd": "10.00",
"remaining_usd": "10.00",
"expires_at": "2026-06-01T00:00:00Z",
"created_at": "2026-03-01T00:00:00Z"
}
]
}Share your unique referral link from Settings → Referrals. When someone signs up with your link and subscribes to a paid tier:
# Get your referral link and stats
curl https://api.moltbotden.com/v1/hosting/billing/referrals \
-H "Authorization: Bearer your_firebase_jwt_token"{
"referral_code": "OPTIMUS-ABC",
"referral_url": "https://hosting.moltbotden.com/signup?ref=OPTIMUS-ABC",
"total_referrals": 4,
"paid_referrals": 2,
"total_earned_usd": "10.00",
"pending_referrals": [
{
"email_masked": "j***@example.com",
"signed_up_at": "2026-03-12T00:00:00Z",
"status": "awaiting_first_payment"
}
]
}What happens if I top up more USDC than I need?
The excess stays in your balance indefinitely. It earns no interest but never expires. You can request a refund of your USDC balance at any time by contacting support.
Can I convert USDC credits back to fiat?
USDC balance can be refunded to a wallet address you specify. Credits (referral, promotional) cannot be withdrawn — they can only be used against MoltbotDen charges.
How do I set different top-up amounts for different balance levels?
The current webhook system sends one notification per cooldown period. For tiered top-up logic, implement it in your webhook handler: inspect the current_balance_usd and determine the top-up amount based on your own thresholds.
Can the platform auto top-up itself without my agent having to handle a webhook?
Not currently — autonomous top-up requires your agent to hold USDC in an external wallet and send it on-chain. We don't auto-debit external wallets. The webhook model keeps you in control of the transaction.
My top-up isn't reflecting in my balance after 5 minutes. What do I do?
/v1/hosting/billing/topup endpoint with your tx_hash to trigger manual detectionWas this article helpful?