Authentication-Based Recovery API (Email / SMS)
A Safe guardian service that uses email and phone verification to facilitate account recovery. It can be used as a default recovery method or combined with other guardians (such as hardware wallets or trusted contacts) to create a customized recovery threshold.
The following API is in a pre-release phase. Request access by contacting us.
Registration: Email / SMS
Submit a registration request with the target smart account to protect using the choice of channel (email or sms).
The user will then receive a OTP code to later submits the challenge in /auth/submit
POST /auth/register
- Example Request
- Example Response
curl -X POST \
https://api.candide.dev/recoveries/$version/$network/$your_api_key/auth/register \
-H 'Content-Type: application/json' \
-d '{
"account":"0x...",
"chainId": 1,
"channel":"email",
"target":"user@example.com",
"timestamp": 1739024754,
"signature": "sign(chainId, channel, target, timestamp)"
}'
{
"challengeId":"unique-challenge-id",
}
account
: The smart account address requesting registration.chainId
: The chain id in which your account resides (for multi-chain wallets, users will need to register per chain)channel
: Either"email"
or"sms"
(defines the authentication type).target
: The email or phone number for authentication.timestamp
: timestamp at signaturesignature
: signature proving the request is initiated from the account
Registration: Submits confirmation using OTP
Submits the receive OTP code to confirm ownership of the target channel
POST /auth/submit
- Example Request
- Example Response
curl -X POST \
https://api.candide.dev/recoveries/$version/$network/$your_api_key/auth/submit \
-H 'Content-Type: application/json' \
-d '{
"challengeId":"unique-challenge-id",
"challenge":"123456"
}'
{
"registrationId": "unique-registration-id",
"guardianAddress": "0x...",
}
challengeId
: The unique challenge ID received in the registration response.challenge
: The code received via email/SMS.
Registration: Get active registration
Fetch the registration of the protected smart account
GET /auth/registrations
- Example Request
- Example Response
curl -X GET \
https://api.candide.dev/recoveries/$version/$network/$your_api_key/auth/registrations \
-H 'Content-Type: application/json' \
-d '{
"account":"0x...",
"chainId": 1,
"timestamp": 1739024754,
"signature": "sign(chainId, timestamp)"
}'
{
"registrations": [
{
"id": "unique-registration-id",
"channel": "email",
"target": "user@example.com",
}
]
}
account
: The safe account address.chainId
: The chain id in which your account resides.timestamp
: timestamp at signaturesignature
: signature proving the request is initiated from the account
Registration: Delete
Deletes a registration
POST /auth/delete
- Example Request
- Example Response
curl -X POST \
https://api.candide.dev/recoveries/$version/$network/$your_api_key/auth/delete \
-H 'Content-Type: application/json' \
-d '{
"registrationId":"unique-registration-id",
"timestamp": 1739024754,
"signature": "sign(registrationId, timestamp)"
}'
{
"success": "true"
}
registrationId
: The registration id.timestamp
: timestamp at signaturesignature
: signature proving the request is initiated from the account
Recovery: Request to recover an account
Request a siganture from the service to recover an account given the new owners and threshold
POST /auth/signature/request
- Example Request
- Example Response
curl -X POST \
https://api.candide.dev/recoveries/$version/$network/$your_api_key/execute \
-H 'Content-Type: application/json' \
-d '{
"account":"0x...",
"newOwners": ["0x...", "0x..."],
"newThreshold": 2,
"chainId": 1
}'
{
"requestId":"unique-signature-request-id",
"requiredVerifications": 1, // minimum number of required challenges that should be submitted for this signature request
"auths": [
{
"challengeId": "unique-challenge-id",
"channel": "email",
"target": "us**@exa****.com"
}
]
}
account
: The smart account address to be recovered.newOwners
: The new owners to the safe accountnewThreshold
: The new threshold to the safe accountchainId
: chain id for the recovery request signature
Recovery: Confirm recovery with OTP challenge
Request to submits the signature with the provided OTP code challenge and id
POST /auth/signature/submit
- Example Request
- Example Response
curl -X POST \
https://api.candide.dev/recoveries/$version/$network/$your_api_key/auth/signature/submit \
-H 'Content-Type: application/json' \
-d '{
"requestId": "unique-signature-request-id",
"challengeId": "unique-challenge-id",
"challenge": "123456"
}'
{
"success": true,
"signer": "0x...", // available only if sufficient verifications were collected
"signature": "0x...", // available only if sufficient verifications were collected
}
requestId
: The unique ID received in the signature request response.challengeId
: The unique challenge ID specific to a authentication method, received in the signature request response.challenge
: The code received via email/SMS.
Alerts: Subscribe to recovery requests
POST /alerts/subscribe
Creates an inactive alerts subscription for an account, both onchain and offchain. It then needs to be activated through challenge submission using POST /alerts/activate
.
- Example Request
- Example Response
curl -X POST \
https://api.candide.dev/recoveries/$version/$network/$your_api_key/alerts/subscribe \
-H 'Content-Type: application/json' \
-d '{
"account": "0x...",
"chainId": 1,
"channel": "email",
"target": "user@example.com",
"timestamp": 1739024754,
"signature": "sign(channel, target, timestamp)"
}'
{
"subscriptionId": "unique-subscription-id", // please note that this alerts subscription needs to be activated using the next endpoint
}
account
: The smart account address requesting registration.chainId
: The chain id in which the account resides (this is used to verify the signature field only, the alert will trigger for any action for this account across any chain)channel
: Either"email"
or"sms"
(defines the delievery channel).target
: The email or phone number for authentication.timestamp
: timestamp at signaturesignature
: signature proving the request is initiated from the account
Alerts: Activate subscripton to recovery requests
POST /alerts/activate
Verifies submitted challenge and activates alerts subscription.
- Example Request
- Example Response
curl -X POST \
https://api.candide.dev/recoveries/$version/$network/$your_api_key/alerts/activate \
-H 'Content-Type: application/json' \
-d '{
"subscriptionId": "unique-subscription-id",
"challenge": "123456"
}'
{
"success": true,
}
subscriptionId
: The unique ID received in the subscription response.challenge
: The code received via email/SMS.
Alerts: Get active subscription
Fetches active alerts subscriptions for an account.
GET /alerts/subscriptions
- Example Request
- Example Response
curl -X GET \
https://api.candide.dev/recoveries/$version/$network/$your_api_key/alerts/subscriptions \
-H 'Content-Type: application/json' \
-d '{
"account": "0x...",
"chainId": 1,
"timestamp": 1739024754,
"signature": "sign(identifier with timestamp)",
}'
{
"subscriptions": [
{
"id": "unique-subscription-id",
"channel": "email",
"target": "user@example.com"
}
]
}
account
: The smart account address.chainId
: The chain id in which the account resides (this is used to verify the signature field only, the alerts are global for this account accross all supported chains that have alerts enabled)timestamp
: timestamp at signature.signature
: signature proving the request is initiated from the account.
Alerts: Unsubscribe
Unsubscribes from an active alerts subscription.
POST /alerts/subscriptions
- Example Request
- Example Response
curl -X GET \
https://api.candide.dev/recoveries/$version/$network/$your_api_key/alerts/subscriptions \
-H 'Content-Type: application/json' \
-d '{
"subscriptionId": "unique-subscription-id",
}'
{
"success": true,
}
subscriptionId
: The unique ID received in the subscription response.