Skip to content

The sandbox and the faucet

There is exactly one test environment, and it is the real public testnets: TRON Nile, BSC testnet and Ethereum Hoodi. There is no simulator. Every Sandbox test exercises the real on-chain path: address derivation, an actual transaction in an actual block, real confirmations, webhooks fired by the chain’s own pace.

That is a deliberate trade. A simulator answers instantly and hides exactly the class of behaviour that surprises integrators in production (confirmation delays, the DETECTED-then-CONFIRMED distinction, a transaction that takes a minute to land). The Sandbox makes you meet those behaviours on day one, with valueless assets.

Practically:

  • Same host, same code, same signing recipe as Live. The cpk_test_ prefix of your key is the only thing that says Sandbox.
  • The stablecoins you receive are CowriePay-issued test tokens on those networks; the native currencies (ETH, BNB, TRX) are the networks’ own test currencies.
  • Timing is real: a TRON deposit confirms in seconds to minutes, an Ethereum one at Hoodi’s pace.

The faucet pre-funds one of your own sandbox wallet addresses with test assets, so you never hunt public testnet faucets. It is POST /v2/sandbox/faucet, requires wallets:write, and only accepts a cpk_test_ key (a live key gets 403 FAUCET_ONLY_SANDBOX).

Request:

{
"chain": "TRON",
"address": "TYourSandboxWalletAddress1234567890",
"assets": [{ "symbol": "USDT_TRON" }]
}

Response (202):

{
"drip_id": "d4e5f6a7-0000-0000-0000-000000000004",
"status": "PENDING",
"chain": "TRON",
"address": "TYourSandboxWalletAddress1234567890",
"items": [
{ "asset": "USDT_TRON", "amount": "1000", "status": "PENDING" }
]
}

The drip is queued, dispatched on-chain, and then arrives as a completely normal deposit: your webhook receives DEPOSIT_DETECTED, then DEPOSIT_CONFIRMED, exactly as it will with a real customer. That is the point: the faucet is a funding shortcut, not a separate code path.

Omit amount to receive the per-asset default (generous for tokens). The dashboard offers the same thing as a pre-fund prompt right after you create a sandbox wallet.

The test tokens (USDT, USDC, EURC) are minted by CowriePay, so they are effectively unlimited and the defaults are generous.

Native currency (ETH, BNB) is different: it is farmed from public testnet faucets, which makes it the genuinely scarce resource. So native is opt-in (request it explicitly in assets), carries a rolling per-asset budget per workspace, and is only released once your workspace has at least one confirmed sandbox token deposit.

Before requesting native, ask yourself if you need it at all: in CowriePay’s custodial model you never need native currency to move tokens. CowriePay funds the gas for consolidations and withdrawals. The only reason to request native is to test a native-asset deposit itself.

Every limit has its own error code, so you always know which wall you hit; the full list with the action to take is in the error codes catalogue. The two worth knowing in advance:

  • FAUCET_NATIVE_REQUIRES_DEPOSIT: drip a token first and let it confirm; native unlocks after.
  • FAUCET_DISPENSER_EXHAUSTED: this one is on us, not you. The shared dispenser is out of native currency; our team is alerted when it fires. Retry later, or request token assets only.

There is currently no way to deterministically trigger a failure scenario (a flagged deposit, an underpayment, a failed webhook delivery). This is a known, planned gap, stated here so you do not go looking for a feature that does not exist. Until it lands, failure handling is exercised in code review and with the error codes catalogue as the contract.

  • Quickstart: the faucet in context, from empty account to credited customer.
  • On-chain concepts: what DETECTED, CONFIRMING and CONFIRMED actually mean.
  • Going live: what changes, and what deliberately does not, when you swap the key.