Resource lifecycles
Every long-lived resource in the v2 API exposes a status field whose value is one of an explicit, enumerated set of lifecycle states. State changes — and only state changes — fire webhook events. This page is the source of truth for both.
State machine is the explicit enumeration of every state a resource can be in plus the allowed transitions between them. Knowing the full set up-front lets you (a) wire deterministic UI, (b) reconcile against your own ledger, and (c) subscribe to exactly the events you care about.
Pool
pending ──init confirmed──▶ live ──reserve >= threshold──▶ migration_triggered ──DAMM v2 active──▶ migrated
│ │ │
└─────────────────────── failed ◀──────────────────────────────────────────────────┘
| State | Meaning |
|---|---|
pending | Row inserted in launched_crews; on-chain init tx not yet finalized. |
live | Bonding curve initialized; trading open. |
migration_triggered | Quote reserve crossed migrationQuoteThreshold from the curve config. |
migrated | Liquidity moved to DAMM v2; bonding curve closed. |
failed | Init tx failed on-chain. |
Events: pool.created, pool.live, pool.migration_triggered, pool.migrated, pool.failed.
Airdrop
tree_built ──init confirmed──▶ initialized ──first claim──▶ claiming ──all leaves claimed──▶ fully_claimed
│ │
└──── admin withdraw ──────┴──▶ vault_drained
Events: airdrop.tree_built, airdrop.initialized, airdrop.claim_started, airdrop.claimed (fires per claim), airdrop.fully_claimed, airdrop.vault_drained.
Stake
unstaked ──stake_nft──▶ staked ──unstake_nft──▶ unstaked
│
└── burn_asset ──▶ burned
Events: stake.acquired, stake.released. (Note: nft.burned is fired on the NFT resource, not on the stake.)
Gold Lock
unlocked ──lock_gold──▶ locked ──duration elapsed──▶ eligible_for_unlock ──unlock_gold──▶ unlocked
Events: gold.locked, gold.unlock_eligible, gold.unlocked.
NFT
┌──stake_nft──▶ staked ──unstake_nft──▶ minted
mint_nft ──▶ minted
└──burn_asset──▶ burned
Events: nft.created, nft.staked, nft.unstaked, nft.burned.
Token
created ──revoke mint─────▶ mint_authority_revoked
│
└─revoke freeze───▶ freeze_authority_revoked ──remaining revoke──▶ fully_immutable
Events: token.created, token.mint_authority_revoked, token.freeze_authority_revoked, token.fully_immutable.
Transaction
unknown ──signature observed──▶ submitted ──landed in block──▶ processing ──supermajority──▶ confirmed ──slot finalized──▶ finalized
│
└── on-chain error ──▶ failed
Events: transaction.submitted, transaction.confirmed, transaction.finalized, transaction.failed.
Fee claims (action events)
Fee claims are not a long-lived resource — they're one-shot actions against a pool. They don't carry a status field, but each successful claim emits an event you can subscribe to:
fee_claim.executed— a DBC, DAMM v2, or surplus claim transaction finalized.fee_claim.split_executed— a claim withkind: "split"finalized; the same recipient breakdown that was on the request is included on the event.
Detection modes
Not every transition can be detected from inside the API process. Each event in the catalog (GET /v2/webhook-event-types) carries a detection field:
synchronous— fires from the route handler as part of the inbound request. Always reliable. Examples:pool.created,airdrop.tree_built. The catalog also defineswebhook.test_event, a meta-event you can fire on-demand viaPOST /v2/webhook-subscriptions/{id}/test.tx_confirmed— fires after the user-signed transaction we returned finalizes on-chain. Requires the transaction watcher to be online. Examples:pool.live,stake.acquired,gold.locked.polling_required— needs a background poller comparing on-chain state at intervals. Not yet shipped. Examples:pool.migrated,gold.unlock_eligible,airdrop.fully_claimed.
See Webhooks for delivery, signing, and retry semantics.