Create Accounts
Provision managed or passkey-owned accounts from your backend.
Create an API key in Settings → Workspace → API keys with wallet:create and wallet:read. These permissions cover all existing and future accounts in that workspace. Keep the API key in your backend environment.
Create a managed account
import { NameraClient } from "@namera-ai/sdk";
const namera = new NameraClient({ apiKey: process.env.NAMERA_API_KEY! });
const result = await namera.wallets.create({
namespace: "eip155",
metadata: { version: 1, name: "Provisioned account" },
owner: { type: "namera-managed", provider: "1claw" },
});
if (!result.success) throw new Error(result.error.message);
console.log(result.data);{
"id": "0199dfe1-0000-7000-8000-000000000001",
"organizationId": "0199dfe1-0000-7000-8000-000000000006",
"metadata": {
"version": 1,
"name": "Provisioned account"
},
"status": "active",
"namespace": "eip155",
"address": "0x3333333333333333333333333333333333333333",
"owner": {
"signingKeyId": "0199dfe1-0000-7000-8000-000000000008",
"custody": "namera-managed",
"provider": "1claw",
"algorithm": "secp256k1"
},
"createdAt": "2026-10-15T02:39:05.250Z",
"updatedAt": "2026-10-15T02:39:05.250Z",
"implementation": "alchemy-modular-v2",
"data": {
"version": 1,
"modularAccountVersion": "2.0.0",
"validatorType": "ecdsa_secp256k1",
"entryPointVersion": "0.7",
"accountMode": "factory",
"factoryVersion": "2.0.0",
"implementationVersion": "v1.0.0",
"ownerAddress": "0x52e7f17258368d7f9Ebd7bDf8d6869Bc4759aBA1",
"salt": "0"
}
}The account is derived and persisted without deploying it. The SDK manages managed-provisioning retry keys internally. Keep the returned ID; use it as walletId when creating sessions.
Create a passkey-owned account
At API-key issuance, allowlist your application’s exact origin, such as https://app.example.com. Each passkey belongs to that RP and origin. Your backend must authenticate its application user and bind the pending verification ID to that user.
Start on your backend
import { NameraClient } from "@namera-ai/sdk";
const namera = new NameraClient({ apiKey: process.env.NAMERA_API_KEY! });
const result = await namera.wallets.createPasskeyRegistrationOptions({
origin: "https://app.example.com",
user: { name: "Customer", displayName: "Customer" },
});
if (!result.success) throw new Error(result.error.message);
console.log(result.data);{
"verificationId": "0199dfe1-0000-7000-8000-000000000022",
"options": {
"challenge": "OuAZdeWe1cPGP8if-E91tdEwtCgFVy68KEuEyXdtaIY",
"rp": {
"id": "app.example.com",
"name": "Namera"
},
"user": {
"id": "MDFhMTNkNmQtNzZkYi03NTUzLWE4M2QtMTFhMzRkNWJhNjFm",
"name": "Customer",
"displayName": "Customer"
},
"pubKeyCredParams": [
{
"alg": -7,
"type": "public-key"
}
],
"timeout": 300000,
"excludeCredentials": [],
"authenticatorSelection": {
"residentKey": "required",
"requireResidentKey": true,
"userVerification": "required"
},
"hints": [],
"attestation": "none",
"extensions": {
"credProps": true
}
},
"expiresAt": "2026-10-15T02:44:06.347Z"
}Persist verificationId in your user’s pending account creation and return options to their browser. Do not expose the API key. Your application owns the start/finish HTTP routes; these are not additional Namera endpoints.
Register in the browser
Install @simplewebauthn/browser in your frontend. In a user-initiated event, call startRegistration({ optionsJSON: options }) with the options your backend returned. Send the complete result to your backend. Browser cancellation should leave the account uncreated.
Finish on your backend
Load verificationId from that authenticated user’s pending creation and submit:
import { NameraClient, type CreateWalletRequest } from "@namera-ai/sdk";
const namera = new NameraClient({ apiKey: process.env.NAMERA_API_KEY! });
export async function finishPasskeyAccount(
verificationId: string,
response: Extract<CreateWalletRequest["owner"], { type: "passkey" }>["response"],
) {
const result = await namera.wallets.create({
namespace: "eip155",
metadata: { version: 1, name: "Customer account" },
owner: { type: "passkey", verificationId, response },
});
if (!result.success) throw new Error(result.error.message);
return result.data;
}{
"id": "0199dfe1-0000-7000-8000-000000000004",
"organizationId": "0199dfe1-0000-7000-8000-000000000015",
"metadata": {
"version": 1,
"name": "Customer account"
},
"status": "active",
"namespace": "eip155",
"address": "0x3333333333333333333333333333333333333333",
"owner": {
"signingKeyId": "0199dfe1-0000-7000-8000-000000000016",
"custody": "local",
"algorithm": "p256"
},
"createdAt": "2026-10-15T02:39:06.474Z",
"updatedAt": "2026-10-15T02:39:06.474Z",
"implementation": "alchemy-modular-v2",
"data": {
"version": 1,
"modularAccountVersion": "2.0.0",
"validatorType": "webauthn_p256",
"entryPointVersion": "0.7",
"salt": "0",
"entityId": 0
}
}The exported function is called by your authenticated finish route after it loads the pending verification. It is not an unauthenticated route accepting arbitrary verification IDs. Registration is single-use and actor-bound. Passkey creation is not automatically retried after a lost response; inspect the workspace account list before attempting a new ceremony.
Next, create a session key.