This guide explains how to enable and manage wallet recovery for your users. Recovery allows users to regain access to their wallet in case of passkey loss or device failure.
Enabling recovery requires two steps: first, prepare the recovery operation, then sign it with a passkey.
Endpoint : POST /v1.2/safes/operations
Headers :
Authorization: Bearer <access_token> (required)Body (JSON) :
safeAddress (string, required) : Safe address for which to enable recoveryoperations (array, required) : Array containing an operation of type ENABLE_RECOVERYENABLE_RECOVERY Operation :
type (string, required) : "ENABLE_RECOVERY"firstName (string, required) : First name for personal datalastName (string, required) : Last name for personal databirthDate (string, required) : Birth date in YYYY-MM-DD formatbirthCity (string, required) : Birth citybirthCountry (string, required) : Birth countryRequest Example :
POST /v1.2/safes/operations
Content-Type: application/json
Authorization: Bearer <access_token>
{
"safeAddress": "0xd676c6188195372EC269E9C2cAf815C56436A679",
"operations": [
{
"type": "ENABLE_RECOVERY",
"firstName": "Jane",
"lastName": "Doe",
"birthDate": "1990-01-01",
"birthCity": "Paris",
"birthCountry": "France"
}
]
}
Response (200 OK) :
{
"credentialRequestOptions": {
"challenge": "<base64url_encoded_userOpHash>",
"rpId": "foo.domain",
"userVerification": "required",
"timeout": 60000,
"allowCredentials": [
{
"id": "<base64url>",
"type": "public-key"
}
]
},
"data": {
"userOpHash": "0xabc...123"
}
}
credentialRequestOptions : WebAuthn options needed for passkey signaturedata.userOpHash : Operation hash for tracking statusEndpoint : PUT /v1.2/safes/operations
Headers :
Authorization: Bearer <access_token> (required)Body (JSON) :
credential (object, required) : WebAuthn credential obtained via navigator.credentials.get() with the options from step 1Request Example :
PUT /v1.2/safes/operations
Content-Type: application/json
Authorization: Bearer <access_token>
{
"credential": {
"id": "AVZs0qRCBSmfThZWu37g...",
"rawId": "AVZs0qRCBSmfThZWu37g...",
"type": "public-key",
"response": {
"authenticatorData": "SZYN5YgOjGh0NBcPZHZgW4/krrmihjLHmVzzuoMdl2MFAAAAAQ...",
"clientDataJSON": "eyJ0eXBlIjoid2ViYXV0aG4uZ2V0IiwiY2hhbGxlbmdlIjoi...",
"signature": "MEUCIQC..."
}
}
}
Response (200 OK) :
{
"userOpHash": "0xabc...123",
"status": "SIGNED",
"safeAddress": "0xd676c6188195372EC269E9C2cAf815C56436A679"
}
SIGNED, then EXECUTED when the bundler submits it to the blockchain, and finally CONFIRMED after block confirmations. Recovery requires a delay (default 1 day = 86400 seconds) before it can be executed. Final execution is performed by the IBEX team via an administrative endpoint after the delay expires.
You can check the recovery status of a Safe to see if recovery is enabled, pending, or can be executed.
Endpoint : GET /v1.1/recovery/status/:safeAddress
Headers :
Authorization: Bearer <access_token> (required)Path Parameters :
safeAddress (string, required) : Safe address (EVM format, case-insensitive)Request Example :
GET /v1.1/recovery/status/0xd676c6188195372EC269E9C2cAf815C56436A679 Authorization: Bearer <access_token>
Response (200 OK) :
{
"safeAddress": "0xd676c6188195372EC269E9C2cAf815C56436A679",
"recoveryEnabled": true,
"recoveryAddress": "0x303f215950f7B07Ae45FD98590d503E0242E7de3",
"delay": 86400,
"pendingRecovery": false,
"canExecute": false,
"executeAfter": null,
"dataRecovery": true,
"pending": [],
"executed": [
{
"userOpHash": "0xdef...456",
"transactionHash": "0x789...abc",
"status": "EXECUTED",
"createdAt": "2025-08-24T16:58:20.100Z",
"updatedAt": "2025-08-24T16:59:10.450Z"
}
]
}
recoveryEnabled : Whether recovery is currently enabled on the SaferecoveryAddress : Address of the recovery guardian (if enabled)delay : Recovery delay in seconds (default: 86400 = 1 day)pendingRecovery : Whether there's a pending recovery operationcanExecute : Whether recovery can be executed (after delay expires)executeAfter : Timestamp when recovery can be executed (if pending)dataRecovery : Whether IBEX Safe holds recovery data for this addresspending : Array of pending recovery operations (status: CREATED, SIGNED)executed : Array of executed recovery operations (status: EXECUTED, CONFIRMED)If a user wants to cancel an ongoing recovery operation, they can use the CANCEL_RECOVERY operation.
Endpoint : POST /v1.2/safes/operations
Body (JSON) :
safeAddress (string, required) : Safe addressoperations (array, required) : Array containing an operation of type CANCEL_RECOVERYCANCEL_RECOVERY Operation :
type (string, required) : "CANCEL_RECOVERY"Request Example :
POST /v1.2/safes/operations
Content-Type: application/json
Authorization: Bearer <access_token>
{
"safeAddress": "0xd676c6188195372EC269E9C2cAf815C56436A679",
"operations": [
{
"type": "CANCEL_RECOVERY"
}
]
}
Response (200 OK) :
{
"credentialRequestOptions": {
"challenge": "<base64url_encoded_userOpHash>",
"rpId": "foo.domain",
"userVerification": "required",
"timeout": 60000,
"allowCredentials": [
{
"id": "<base64url>",
"type": "public-key"
}
]
},
"data": {
"userOpHash": "0xdef...456"
}
}
Endpoint : PUT /v1.2/safes/operations
Same as Step 2 of Enable Recovery. Submit the WebAuthn credential to finalize the cancellation.
Request Example :
PUT /v1.2/safes/operations
Content-Type: application/json
Authorization: Bearer <access_token>
{
"credential": {
"id": "AVZs0qRCBSmfThZWu37g...",
"rawId": "AVZs0qRCBSmfThZWu37g...",
"type": "public-key",
"response": {
"authenticatorData": "SZYN5YgOjGh0NBcPZHZgW4/krrmihjLHmVzzuoMdl2MFAAAAAQ...",
"clientDataJSON": "eyJ0eXBlIjoid2ViYXV0aG4uZ2V0IiwiY2hhbGxlbmdlIjoi...",
"signature": "MEUCIQC..."
}
}
}
This section provides detailed technical information for AI systems integrating the IBEX API recovery functionality.
The recovery system uses a Safe module pattern:
Step 1: POST /v1.2/safes/operations
enableModule(recoveryModuleAddress)enableRecovery(guardian, cooldown, expiration)credentialRequestOptions with challenge = userOpHash (base64url encoded)Step 2: PUT /v1.2/safes/operations
verifyAuthenticationResponse()SIGNEDEXECUTED)Step 1: POST /v1.2/safes/operations
cancelRecovery() on RecoveryModulecredentialRequestOptions for passkey signatureStep 2: PUT /v1.2/safes/operations
GET /v1.1/recovery/status/:safeAddress
SafeOperation Status Flow for Recovery:
CREATED : Operation created, awaiting passkey signatureSIGNED : Passkey signature received, operation ready for bundlerEXECUTED : Bundler submitted userOp to blockchain, awaiting confirmationCONFIRMED : Sufficient block confirmations receivedsrc/routes/v1/safesOperations.ts : ENABLE_RECOVERY and CANCEL_RECOVERY operation handlerssrc/routes/v1.1/recovery.ts : Recovery status endpointsrc/clients/IbexSafe.ts : Safe.ib.exchange service integration