What triggers a sweep
Sweeps are triggered automatically after finality is confirmed. Three callers can initiate a sweep:- Inline finalize — the
paymentVerifyInngest workflow triggers sweep immediately after marking the sessionpaid. - Manual retry — the dashboard’s Payouts page lets you retry failed sweeps.
- Hourly cron — the
reconcileAlchemyjob also catches any sessions that slipped through.
The sweep state machine
Stage descriptions
Atomic claim: no double-sweeps
The sweep uses anUPDATE … RETURNING query that only succeeds if the payout row’s stage is pending, failed, or skipped — or if it’s been in sweeping, gas_funded, or broadcasting for more than 10 minutes (treated as a crashed worker). If the claim returns no rows, another worker owns it and this caller exits.
This is the single mechanism that prevents two callers from broadcasting competing transactions.
Crash safety: hash persisted before confirm
The transaction hash is written to the database the instant the transaction is broadcast, before waiting for the receipt. If the process crashes between broadcast and confirm, the hash is already recorded. When sweep is retried, it detectsbalance == 0 + sweepTxHash is set and marks the payout swept without re-broadcasting.
When sweeps are skipped
Manual retries bypass the dust filter — if you click Retry on a low-value payout, it sweeps regardless of
sweepMinUsd.
Token sweeps
For ERC-20 tokens, the deposit address typically has no native gas (ETH) to pay for the transfer. The sweep handles this automatically:- The gas wallet sends a small ETH top-up to the deposit address (
gas_fundedstage). - The deposit address uses that ETH to call the ERC-20
transfer()function to the payout wallet.