Sign-up with passkey 1/2
Enhanced signup endpoint (v1.2) supporting 4 authentication methods.
rpId (tenant identification):
The rpId (Relying Party Identifier) is a domain string that scopes users, wallets, and credentials to your application. Each rpId is an isolated namespace — users created under one rpId are invisible to another. It also serves as the WebAuthn rpId, so the browser enforces that it matches your page origin.
Your rpId must be registered with IBEx. Pass it via:
- Query parameter:
?rpId=yourdomain.com - Header:
X-RpId: yourdomain.com - Automatically via Origin header (browser requests)
If missing or unregistered, returns 400 Unknown domain/rpId.
For local development, localhost is automatically recognized.
See the full [rpId guide](/docs/guides/integration/rpid) for production setup, WebAuthn constraints, and common errors.
---
Query parameters reference:
| Parameter | Type | Required for |
|-----------|------|-------------|
| wallet | string | All modes (passkeys default, kdf, email, 7702) |
| email | string | wallet=email only |
| address | string | wallet=7702 only (0x-prefixed, 42 chars) |
| chainId | number | wallet=7702 (optional, defaults to project chain) |
| user.name / userName | string | wallet=passkeys (optional, WebAuthn override) |
| user.displayname / userDisplayName | string | wallet=passkeys (optional, WebAuthn override) |
| keyName / keyDisplayName | string | wallet=passkeys (optional, display labels) |
| passkeys | string | ⚠️ Deprecated — use wallet instead |
| flow | string | ⚠️ Deprecated — use wallet=kdf instead |
---
### 1. Passkeys Safe wallet (wallet=passkeys, default)
What it means?
Creates a new user account backed by a WebAuthn passkey (biometric / security key). The browser generates a cryptographic key pair; the public key is registered as the signer for a new Safe Smart Contract Wallet (ERC-4337). This is the most secure mode — the private key never leaves the device.
Next step: POST the credential returned by navigator.credentials.create() to POST /sign-up.
---
### 2. KDF Safe wallet (wallet=kdf)
What it means?
Creates a user account where the signer key is derived client-side from a user-chosen PIN/password using Argon2id. The server never sees the PIN — it only provides the salt and KDF parameters. A server-signed challenge prevents replay attacks. Ideal for devices without biometric/passkey support.
Next step: Derive the key from PIN + salt, sign the canonical message, and call POST /sign-up with the signature proof.
---
### 3. Email Safe wallet (wallet=email, requires email)
What it means?
Creates an account where a one-shot email OTP (30 seconds) verifies the user's email address. The client generates a key pair locally and encrypts the private key with a user passphrase before sending it to the server as a backup. The server stores only the encrypted blob — it can never access the real key. Useful for email-first onboarding.
Next step: Verify the OTP via POST /email/recover, then call POST /sign-up with the signature proof.
---
### 4. EOA + EIP-7702 (wallet=7702, requires address)
What it means?
Registers an existing Externally Owned Account (EOA) and turns it into a Smart Account via EIP-7702 delegation to SafeEIP7702Proxy. The user signs a SIWE-like challenge with their wallet (MetaMask, WalletConnect, etc.). After sign-up, the backend creates a PENDING delegation record — the client must broadcast the EIP-7702 authorization transaction on-chain to activate Smart Account features (modules, batching, recovery).
Next step: Sign challenge with the wallet and call POST /sign-up with { wallet: "7702", address, signature, nonce }.
Query Parameters
walletstringAuthentication mode: passkeys (default), kdf, email, or 7702
"passkeys" | "kdf" | "email" | "7702"passkeysDeprecatedstring[Deprecated] Use wallet=passkeys or wallet=kdf instead
"TRUE" | "FALSE"flowDeprecatedstring[Deprecated] Use wallet=kdf instead
"pin-kdf"emailstring[Email mode only] Email address to receive OTP
addressstring[7702 mode only] EOA address (0x-prefixed, 42 chars)
chainIdnumber[7702 mode only] Target blockchain chain ID
user.namestring[Passkeys mode] Override WebAuthn user.name
user.displaynamestring[Passkeys mode] Override WebAuthn user.displayName
userNamestring[Passkeys mode] Alias for user.name
userDisplayNamestring[Passkeys mode] Alias for user.displayname
keyNamestring[Passkeys mode] Passkey display name stored server-side
keyDisplayNamestring[Passkeys mode] Passkey display label stored server-side
Signup challenge (format depends on wallet mode)