Research & Deep Dives
Supporting material for the DBZ Developer Platform case study — infrastructure details, code samples, error references, regulatory analysis, and success metrics.
Shared Infrastructure
Authentication, response formats, webhooks, and conventions shared across all endpoints
Authentication & Security
All requests are scoped to a project and authenticated via the apikey header.
curl -H "apikey: your_project_api_key" \
https://api.dbzpay.com/v1/project/balance
Keys can be restricted to specific permissions: payout:read, payout:write, user:read, ledger:write. Production keys should use minimum required scopes.
POST /v1/api-keys/rotate enables zero-downtime rotation. The old key remains valid for 24 hours after rotation.
Production keys support IP allowlisting to restrict API access to known server addresses.
X-DBZ-Signature header with HMAC-SHA256 of the raw request body using your webhook secret.
Idempotency-Key header on POST requests prevents duplicate operations. Keys are unique per-project and expire after 24 hours.
Base URL
https://api.dbzpay.com/v1
Response Envelope
All responses use a standard envelope:
{
"success": true,
"message": "Human-readable status",
"data": { ... }
}
Error Format
{
"success": false,
"message": "Human-readable error description",
"error": {
"code": "kyc_required",
"type": "invalid_request",
"param": "userId",
"retryable": false
}
}
Rate Limiting
All responses include rate limit headers. Default: 1,000 requests/minute per API key.
X-RateLimit-Limit: 1000
X-RateLimit-Remaining: 997
X-RateLimit-Reset: 1679529600
Sandbox vs. Production
Sandbox Base URL: https://sandbox.api.dbzpay.com/v1
- All sandbox object IDs prefixed with
test_(e.g.,test_po_m4n5o6p7) - Includes test fixtures: pre-verified users, simulated KYC flows
- Trigger amounts:
$9.99always fails,$1.00always succeeds
Project Management
| Method | Endpoint | Description |
|---|---|---|
| GET | /v1/project/balance | Get your project's current balance (available funds for payouts + prize pools). |
| GET | /v1/project/transactions | Project-level transaction history (top-ups, payouts, fees, escrow holds). |
Webhook Management
| Method | Endpoint | Description |
|---|---|---|
| POST | /v1/webhooks | Register a webhook endpoint URL. Specify which events to subscribe to. |
| GET | /v1/webhooks | List registered webhook endpoints. |
| PATCH | /v1/webhooks/{webhookId} | Update a webhook endpoint (URL, events, active/inactive). |
| DELETE | /v1/webhooks/{webhookId} | Delete a webhook endpoint. |
| POST | /v1/webhooks/{webhookId}/test | Send a test event to verify your endpoint is receiving correctly. |
This is an upgrade from DBZ's current per-request callbackUrl pattern to global webhook subscriptions (Stripe-style). The callbackUrl pattern is still supported for backwards compatibility.
Webhook Delivery Guarantees
eventId field to deduplicate.timestamp and object status to determine current state.GET /v1/events returns a log of all events. Filter by type, createdAfter, createdBefore. Use this to replay missed events during outages.Multi-Currency Support
All monetary amounts use the smallest unit of the specified currency (cents for USD, centimes for EUR). The currency field accepts ISO 4217 codes. Supported at launch: usd, eur.
- Wallet balances are per-currency (a user can hold both USD and EUR)
- Cross-currency payouts supported: DBZ handles FX conversion, disclosed via
fxRateandfxFeefields - Tournament entry fees and prizes must be in a single currency per tournament
Code Samples
Node.js SDK examples for common integration patterns
Create a Payout
import DBZ from '@dbz/node';
const client = new DBZ('your_api_key');
// Create a payout (idempotency key goes in the options, sent as header)
const payout = await client.payouts.create({
userId: 'usr_a1b2c3d4',
bankAccountId: 'ba_x9y8z7',
amount: 5000,
currency: 'usd',
description: 'Tournament winnings',
internalId: 'match_789',
metadata: { gameId: 'battle-royale-2' }
}, {
idempotencyKey: 'payout_unique_abc123'
});
console.log(payout.data.id); // "po_m4n5o6p7"
console.log(payout.data.status); // "pending"
Webhook Handler
import express from 'express';
import DBZ from '@dbz/node';
const app = express();
const client = new DBZ('your_api_key');
// IMPORTANT: Use express.raw() to get the raw body for signature verification
app.post('/webhooks/zbd', express.raw({ type: 'application/json' }), async (req, res) => {
const signature = req.headers['x-dbz-signature'];
// req.body is a raw Buffer here — required for HMAC verification
if (!client.webhooks.verify(req.body, signature)) {
return res.status(401).send('Invalid signature');
}
const { event, data } = JSON.parse(req.body);
switch (event) {
case 'payout.completed':
await markPayoutComplete(data.internalId, data.amount);
break;
case 'payout.failed':
await handlePayoutFailure(data.internalId, data.failureCode);
break;
case 'payout.returned':
// Bank returned funds — re-credit player's in-game balance
await reverseGamePayout(data.internalId, data.amount);
break;
}
res.status(200).send('OK');
});
Error Codes Reference
Comprehensive error and failure codes across all API endpoints
Payout to Bank — Failure Codes
| Code | Description | Retryable |
|---|---|---|
insufficient_project_balance | Project doesn't have enough funds to cover payout | Yes (after top-up) |
kyc_required | User hasn't completed required KYC tier | No (redirect user to verify) |
kyc_pending | KYC submitted but not yet approved | Yes (after approval) |
kyc_rejected | KYC verification failed | No |
payout_limit_exceeded | Exceeds user's tier limit | No (upgrade tier) |
bank_account_not_verified | Bank account linking not complete | No |
invalid_bank_account | Bank account details invalid | No (re-link) |
bank_account_closed | Destination account is closed | No (re-link) |
account_frozen | DBZ flagged account for review | No (contact support) |
sanctions_match | User flagged by sanctions screening | No |
duplicate_payout | Idempotency key already used | No |
amount_too_small | Below minimum payout ($1.00) | No |
amount_too_large | Exceeds single-payout maximum | No (split into multiple) |
velocity_limit | Too many payouts in time window | Yes (after cooldown) |
internal_error | DBZ system error | Yes (with backoff) |
Wallet Loading — Error Codes
| Code | Description | Retryable |
|---|---|---|
bank_account_not_linked | No verified bank account | No (link first) |
insufficient_bank_funds | Player's bank account has insufficient funds | Yes (after player adds funds) |
load_limit_exceeded | Daily/monthly load limit reached | Yes (after limit resets) |
kyc_required | KYC tier insufficient for wallet loading | No (upgrade tier) |
wallet_suspended | Wallet suspended for review | No |
duplicate_load | Idempotency collision | No |
Virtual Currency — Error Codes
| Code | Description | Retryable |
|---|---|---|
insufficient_virtual_balance | User doesn't have enough virtual currency | No |
conversion_limit_exceeded | Daily conversion limit reached | Yes (after reset) |
below_minimum_conversion | Amount below minimum conversion threshold | No |
kyc_required | KYC tier insufficient for conversion | No |
currency_not_found | Invalid currency ID | No |
reward_pool_depleted | Project's reward pool is empty | Yes (after top-up) |
velocity_limit | Too many ledger operations in time window | Yes (after cooldown) |
Tournaments — Error Codes
| Code | Description | Retryable |
|---|---|---|
tournament_full | Max players reached | No |
tournament_not_open | Tournament not accepting entries | No |
insufficient_wallet_balance | Player can't cover entry fee | Yes (after wallet load) |
region_restricted | Player's location not eligible for cash tournaments | No (offer virtual currency instead) |
age_verification_required | Player hasn't verified age 18+ | No (complete KYC) |
already_entered | Player already in this tournament | No |
min_players_not_met | Tournament canceled — not enough entries | No (auto-refund) |
results_mismatch | Submitted rankings don't match entry list | No (resubmit) |
Webhook Events Reference
All webhook event types across the platform
Users & Identity
user.created— New user registereduser.kyc.submitted— Player started verificationuser.kyc.approved— Verification passed (includeskycTier)user.kyc.rejected— Verification failed (includesreason)user.kyc.tier_upgraded— User qualified for higher tier
Payout to Bank
payout.pending— Payout created, awaiting processingpayout.processing— Submitted to banking partnerpayout.in_transit— Funds left DBZ, in transit to bankpayout.completed— Funds deposited successfullypayout.failed— Payout failed (includesfailureCode+failureMessage)payout.canceled— Payout canceled by developerpayout.returned— Bank returned the deposit after completion
Wallet Loading
wallet.load.pending— Load initiatedwallet.load.completed— Funds added to walletwallet.load.failed— Load failed (includes reason)wallet.balance.updated— Balance changed (any reason)
Checkout
checkout.completed— Payment succeeded, credit items to playercheckout.failed— Payment failedcheckout.refunded— Refund processedcheckout.dispute.created— Chargeback initiatedcheckout.dispute.resolved— Chargeback resolved (won or lost)
Virtual Currency
ledger.credited— Virtual currency credited to userledger.debited— Virtual currency debited from userledger.transfer.completed— P2P transfer completedconversion.pending— Conversion requestedconversion.completed— Conversion processed, wallet creditedconversion.failed— Conversion failed (includes reason)
Tournaments
tournament.created— Tournament createdtournament.entry.confirmed— Player successfully enteredtournament.entry.rejected— Entry rejected (ineligible region, insufficient funds, etc.)tournament.started— Tournament now activetournament.results.submitted— Results received, processing prizestournament.settled— All prizes distributedtournament.canceled— Tournament canceled, refunds issued
Regulatory Landscape
Legal framework for paying players real money
Why This Is Not Gambling
US gambling law requires three elements: Prize + Chance + Consideration. Remove any one element and the activity is not gambling. In the studio-funded rewards model (studio pays players from its own budget, no buy-in from players), there is no consideration — the player pays nothing to participate. This means it fails the gambling test in most jurisdictions.
The model is legally classified as a promotional reward / marketing incentive — similar to a loyalty program. It is not a sweepstakes (rewards are deterministic, not chance-based) and not employment income (though the IRS still taxes it).
Risk Matrix
| Area | Risk Level | Detail | DBZ Mitigation |
|---|---|---|---|
| COPPA (minors) | HIGH | Paying players under 13 requires collecting PII, triggering COPPA. Penalties: $53,088 per violation. | Age-gate rewards to 18+. KYC Tier 1+ requires age verification. DBZ handles this in the hosted verification flow. |
| Tax reporting (1099) | MEDIUM | Studios must issue 1099-MISC when payouts exceed $2,000/year (2026+ threshold per OBBBA). At $0.25/match, a player needs 8,000 wins to trigger. | DBZ collects W-9s during KYC Tier 2 and auto-generates 1099s. Studio never handles tax data. |
| State restrictions | MEDIUM | ~9 states restrict skill-based real-money gaming (AZ, AR, CT, DE, LA, MT, SC, SD, TN). These laws mostly target buy-in models, but are untested for studio-funded rewards. | DBZ's is-supported-region API enables geo-fencing. Rewards disabled in restricted states automatically. |
| FTC / dark patterns | MEDIUM | Advertising "earn real money" when typical earnings are $0.25/match could be deceptive. FTC fined Epic $520M (2022) and miHoYo $20M (2025) for gaming dark patterns. | Require studios to display average earnings. DBZ dashboard provides disclosure templates and earnings analytics. |
| Gambling classification | LOW | No player buy-in means no "consideration" element. Fails the three-element gambling test. Guaranteed rewards (not chance-based) also remove the "chance" element. | API design enforces separation: reward endpoints have no buy-in parameter. Tournament endpoints (with buy-in) use separate compliance flows. |
| Platform ToS (Apple/Google) | LOW | Play-to-earn apps (Mistplay, DBZ games, Swagbucks) already exist on both stores. Apple approved DBZ's SaruTobi with Bitcoin microtransactions. | Structure as promotional rewards. DBZ's existing App Store precedent de-risks this for new studios. |
Tournament Buy-Ins: Different Rules Apply
When players pay to enter a tournament, consideration IS present. The gambling test then hinges on whether outcomes are predominantly skill-based or chance-based:
| Model | Consideration | Chance vs Skill | Legal Classification | States Allowed |
|---|---|---|---|---|
| Studio-funded rewards | None (studio pays) | N/A | Promotional reward | ~50 states |
| Skill tournament (buy-in) | Yes (player pays entry) | Predominantly skill | Skill-based gaming | ~41 states |
| Chance-based contest | Yes | Predominantly chance | Gambling (requires license) | Varies (heavily regulated) |
DBZ's tournament API is designed for skill-based competitions only. The skillCertification field on tournament creation requires studios to attest that game outcomes are predominantly skill-determined. DBZ geo-fences tournaments with buy-ins out of the ~9 restricted states automatically.
Industry Precedent
| Company | Model | Compliance Strategy |
|---|---|---|
| Mistplay | Points redeemable for gift cards | Caps redemptions at $550/year per user (under 1099 threshold). Requires 18+. Not a party to financial transactions. |
| Swagbucks | Points for surveys, games, shopping | Issues 1099-NEC at threshold. Collects tax info before allowing further redemptions. Each platform has independent threshold. |
| Skillz | Skill-based tournaments with buy-in | Geo-restricts to ~41 states. Skill certification process. No players under 18. Licensed in applicable jurisdictions. |
| DBZ (current) | Lightning micropayments as gameplay rewards | Holds US MTLs + EU MiCAR/EMI. Micropayments so small they rarely hit reporting thresholds. 120M+ transactions/year. |
Why this strengthens DBZ's value proposition: Compliance is the hardest part of paying players. A studio like 343 Industries doesn't want to deal with 1099s, age-gating, state-by-state geo-fencing, and COPPA audits. DBZ handles all of it behind the API — the studio calls
POST /v1/payoutsand DBZ manages the regulatory complexity. That's the moat.
Compliance Deep Dive
PII edge cases, payout compliance flow, and developer communication strategy
Payout Compliance Flow
PII Edge Cases & Mitigations
| Edge Case | Risk | Mitigation |
|---|---|---|
| Customer support | Player contacts the game studio about a failed payout — studio may need info to troubleshoot | Support handoff flow: POST /v1/support/tickets creates a DBZ support case linked to a userId. Player is redirected to DBZ's support portal. Developer never handles the PII. |
| Chargeback disputes | Card network sends dispute evidence requests that may contain buyer PII | Dispute proxy: DBZ acts as the Merchant of Record for checkout transactions. Developer receives only checkout.dispute.created webhook with dispute ID and amount — no PII. |
| Tax reporting for developer-funded prizes | Who is the "payor" for 1099-NEC purposes when the developer funds tournament prizes? | DBZ as payor of record: DBZ is the entity transmitting money to players, making DBZ responsible for tax reporting. Same model Skillz uses. |
| Player communications | Developer wants to email players about payouts — needs at minimum an email address | Scoped consent: POST /v1/users accepts email as an optional field the developer provides at registration. This is data the developer already has from their own signup flow. |
How We Communicate Compliance to Developers
- "Zero PII" badge on every relevant API page — visual indicator that the endpoint keeps developers out of PCI/PII scope.
- "Honest edge cases" section — proactively list edge cases with mitigations. Builds trust vs. making claims that fall apart under scrutiny.
- Compliance checklist in integration guide:
- You handle: game logic, reward rules, player UX
- DBZ handles: identity verification, bank data, sanctions, tax reporting, dispute resolution
- You never need: PCI certification, OFAC screening, 1099 filing, money transmitter license
- "What you don't build" section — explicitly list everything DBZ handles so developers feel confident.
- Sandbox with compliance simulation — test KYC flows, trigger failure scenarios, simulate returns, test dispute handling.
Execution Risks
Key risks to the 6-month phased roadmap and mitigation strategies
| Risk | Impact | Mitigation |
|---|---|---|
| Banking partner compliance review delays Phase 1 | Entire roadmap shifts right | Start banking partner conversations before engineering begins. Have backup partners identified. |
| KYC drop-off exceeds benchmarks | Low payout adoption | Tier 0 (no KYC) lets players engage immediately. Monitor conversion funnel weekly. |
| Skill gaming legal review blocks cash tournaments | Limited geo coverage | Virtual currency tournaments launch everywhere. Cash tournaments roll out state-by-state. |
| Stripe/Xsolla announces competing product | Competitive pressure | Accelerate micropayment support and tournament escrow — features they'd need 12+ months to build. |
Fallback Plan
If timeline slips, Phase 1 (payouts) is the non-negotiable MVP. If we're behind, we ship payouts + wallet loading in months 1-4 and push virtual currency + tournaments to months 5-9, extending to a 9-month roadmap. The brief says payout-to-bank is the primary focus — we protect that.
Success Metrics
Measuring DX quality, integration adoption, and commercial outcomes
DX Quality
| Metric | Target | How to Measure |
|---|---|---|
| Time to first API call | <15 min | Sandbox analytics |
| Time to first payout (sandbox) | <1 hour | Funnel tracking |
| API p99 latency | <500ms | APM |
| API error rate (non-client errors) | <0.1% | Monitoring |
| Doc page completion rate | >80% per guide | Analytics |
| Support tickets per integration | <5 during onboarding | Zendesk |
Integration Adoption
| Metric | Target (6mo) | How to Measure |
|---|---|---|
| Studios with API keys | 50+ | Dashboard |
| Studios live in production | 15+ | First production payout |
| Integration completion rate | >40% (signup to live) | Funnel |
| Monthly active integrations | 12+ | API call volume |
| SDK adoption rate | >60% of integrations use SDK | SDK vs raw API calls |
Commercial Outcomes
| Metric | Target (6mo) | How to Measure |
|---|---|---|
| Total payout volume (GMV) | $2M+ monthly | Ledger |
| Payout success rate | >95% | Payout status tracking |
| Revenue per integration | $5K+ monthly avg | Billing |
| Net revenue retention | >120% | Cohort analysis |
| Time-to-live | <14 days (signup to first prod payout) | Funnel |