Every write on YouthChain is asynchronous: an endpoint hands you a transaction hash, and the result exists a few blocks later. This page is the contract for the other half — how your UI learns that the thing actually happened.
Blocks are produced every ~5 seconds. Every cadence on this page derives from that. A UI that polls every second just burns four requests waiting for a round that has not happened yet.

Pick the right mechanism

1. WebSocket — newHeads

Each notification carries a standard Ethereum header — number, hash, parentHash, timestamp, stateRoot, gasUsed, baseFeePerGas, miner, transactions, plus a YouthChain extra, ycCommitSigners (the validator indices whose signatures committed the block).
newHeads is the only subscription that exists. Any other value — logs, newPendingTransactions — is refused with only newHeads subscription is supported (-32601). To react to a contract event, watch heads and then call eth_getLogs for the range you care about.
Unsubscribe with eth_unsubscribe and the id you were given. Reconnect on close: a dropped socket loses every subscription, and the app must re-subscribe and backfill the blocks it missed via eth_getBlockByNumber.
Debugging with curl? Force HTTP/1.1 — curl --http1.1 -i -N -H "Connection: Upgrade" -H "Upgrade: websocket" .... Over HTTP/2 the upgrade is refused with 400, which looks like a broken endpoint and is not. Browser and Node clients negotiate this correctly on their own.

2. Polling a receipt

For “did my transaction land”, polling the receipt is simpler than a subscription and costs one request per block:
A receipt normally appears within one or two blocks — budget 60 s before declaring failure, and never below 15 s.
The public RPC is served by an archive node that syncs from the validators, so a receipt can appear a beat after the block that contains it. If you poll a receipt in a tight loop and get null for a transaction you just sent, that is the lag, not a failure.

3. Async REST endpoints

Some REST endpoints do several transactions and answer before they settle. They return 202 Accepted with the hashes and a pollUrl.

Faucet

The three transfers (native gas, YCE, YCR) are submitted immediately and land within a few blocks. Poll the pollUrl until nativeBalance is non-zero:
Measured on the live testnet: the POST answers in under a second, and the balance is visible ~15 s later.
The faucet used to hold the connection until all three receipts existed, which took ~40 s and exceeded the default timeout of most HTTP clients — a working faucet looked broken. If you have an older client that treats a slow response as failure, it can be simplified: the answer is immediate now.

Engagement

POST /api/mobile/engagement returns a txHash right away with status: "pending". The reward is visible once the block is committed:
Send an Idempotency-Key header so a network retry replays the original response instead of recording the action twice — mobile networks retry on their own, and a double like is a double mint.

Cadence cheat sheet

Prefer one newHeads subscription per app over N polling loops: one socket tells every screen that the chain moved, and each screen refetches only what it shows.