Many apps want to give users self-custodial wallets while ensuring the server must approve every transaction, wallet update, and key export. A 2-of-2 key quorum achieves this: one quorum member is the user, the other is an authorization key controlled by your server. Both must sign every request to Privy’s API. This means that even if a user’s account is compromised, an attacker cannot take unilateral action with the wallet. Equally, your server alone cannot move funds without the user’s consent. At a high-level, you will:Documentation Index
Fetch the complete documentation index at: https://docs.privy.io/llms.txt
Use this file to discover all available pages before exploring further.
Create a server authorization key
Generate a P-256 keypair and register the public key with Privy. Your server holds the private
key and uses it to co-sign every request.
Create a 2-of-2 key quorum
Register a key quorum that contains the user ID and the server authorization key, with an
authorization_threshold of 2.Create a wallet owned by the quorum
Create a wallet whose owner is the key quorum. All subsequent actions on this wallet require
both signatures.
1. Create a server authorization key
Your server needs a P-256 keypair. The private key stays on your server; the public key is registered with Privy so it can verify your server’s signatures.Create authorization keys
Generate a keypair and register it in the Privy Dashboard or via SDK.
serverAuthorizationPrivateKey in later steps.
2. Create a 2-of-2 key quorum
Once you have the server authorization key’s public key and the user’s Privy user ID, register a key quorum that requires both to sign.3. Create a wallet owned by the quorum
Create a wallet and set itsowner_id to the key quorum ID from step 2.
4. Execute transactions with both signatures
Every request to the Privy API that acts on this wallet must include signatures from both the user and the server. The flow below applies to transactions, wallet updates, and key export.How it works
Step-by-step
Build the request payload on the client
Construct the JSON payload describing the request your app intends to make to the Privy API.
This payload includes the target URL, HTTP method, required headers, and request body.
- React
- React Native
Sign the payload with the user's key on the client
Use the
useAuthorizationSignature hook to sign the payload with the authenticated user’s
signing key. The hook handles key retrieval and signing entirely on the client — the user’s
private key never leaves the device.- React
- React Native
Send the payload and user signature to your server
Forward both the request payload and the user’s signature to your server. Your server will add
its own signature before proxying the request to the Privy API.
Learn more
Key quorums
Learn how key quorums define ownership and authorization thresholds.
Authorization keys
Create and manage server-controlled authorization keys.
Policies
Restrict which transactions are allowed with wallet policies.

