Transaction lifecycle
From signing through submission, confirmation and finality — and how status reaches you.
Transaction lifecycle
Transaction lifecycle
Track a prepared operation from signing through submission, confirmation, and finality.
Prepare once, sign what the rail asks for, then follow the operation id to a terminal state.
operationId is the stable correlation key for tracking each operation. A self-funded native transfer receives it on submit; other flows receive it on prepare. In prepare responses, userOperationHash identifies a UserOperation. In submit and status responses, the same field can contain a request hash on the executor or sponsored rail, or a transaction hash on the self-funded rail. transactionHash is the current outer transaction hash and can change during replacement or recovery.
Submit is idempotent. If it times out, resend the same signed payload with the same operationId when the rail requires one. Identical self-funded transaction bytes resolve to the same operation. Keep polling that id. Do not prepare a replacement while the operation is active. A fresh signature can authorize another execution: use the rail-specific reason and canRetry guidance before signing again.
- 01
Prepare
Prepare the operation and read its rail. Keep operationId as the stable tracking key when prepare returns it. A self-funded native transfer receives its id on submit; a self-funded swap receives one on prepare and expires after 5 minutes. Other prepared operations expire after 30 minutes by default.
- 02
Sign what the rail returns
Sign the userOperationHash, the EIP-712 signingPayload, or the whole transaction, depending on the rail. Attach an EIP-7702 authorization only when the prepare response set authorizationRequired.
- 03
Submit and track
Submit the signature or signedTransaction required by the rail, then poll GET /transaction/{id} with the returned operationId. The transactionHash is the current outer transaction hash and can change when that transaction is replaced; replacementCount counts how often it has.
- 04
Confirm and finalize
Treat confirmed as mined and finalized as reorg-safe. Keep polling the same operationId if a reorg returns the operation to submitted.
Status updates
Status updates
Poll by operation id and process mirrored lifecycle fields idempotently; public webhook subscriptions are not currently available.
Use polling as the public integration contract and tolerate retried synchronization.
| Status | Meaning | Client action |
|---|---|---|
unknown | No lifecycle record has been established for this operation yet. | Keep polling by operationId before preparing a replacement operation. |
received | The operation is recorded and waiting to enter the submission queue. | Keep polling by operationId; do not create a replacement while it remains active. |
queued | The operation is queued for submission. | Keep polling by operationId; do not create a replacement while it remains active. |
submitted | The operation has a current outer transactionHash and is awaiting a mined receipt. | Keep polling by operationId because the current transactionHash can change during replacement. On the self-funded rail a reason of SPEED_UP_REQUIRED with canRetry means the account must re-sign the same nonce at a higher fee. |
confirmed | The operation was mined but has not yet reached the network's reorg-safe depth. | Do not retry; continue tracking until finalized if reorg safety matters. |
finalized | The mined operation reached the network's configured reorg-safe confirmation depth. | Do not retry; this is the successful reorg-safe state. |
failed | Execution was decided by the chain and reverted, so the operation will not advance. | Inspect the reported reason, correct the cause, then prepare and sign a new operation. |
dropped | Tracking stopped without a confirmed execution. This is not proof that the signed transaction cannot land later; the status can change if a receipt is found. | Inspect the rail, reason, canRetry and any transactionHash before taking further action. On the self-funded rail, dropped alone never authorizes a fresh signature: the original bytes may still execute. Re-sending identical bytes is distinct from preparing a new operation. |
{
"operationId": "op_a1b2c3d4e5f6",
"status": "confirmed",
"transactionHash": "0xdef...",
"userOperationHash": "0xabc...",
"networkId": "137",
"replacementCount": 0,
"reason": null
}