Skip to main content
Create smart account with passkey
curl --request POST \
  --url https://grid.squads.xyz/api/grid/v1/passkeys/account \
  --header 'Authorization: Bearer <token>' \
  --header 'Content-Type: application/json' \
  --header 'x-grid-environment: <x-grid-environment>' \
  --data '
{
  "authenticatorResponse": {},
  "sessionKey": {
    "expiration": 1,
    "key": "11111111111111111111111111111111"
  },
  "slotNumber": 1,
  "adminAddress": "<string>",
  "memo": "<string>"
}
'
{
  "address": "5nPmK...smartAccountAddress",
  "type": "passkey",
  "status": "active",
  "policies": {
    "threshold": 1,
    "admin_address": null
  },
  "authentication": [
    {
      "provider": "passkey",
      "session": {
        "Passkey": {
          "passkey_account": "7xK2...passkeyAddress",
          "pubkey": "base58EncodedPublicKey",
          "relying_party_id": "grid.squads.xyz",
          "session_key": {
            "key": "sessionPublicKey",
            "expiration": 1706832000
          }
        }
      }
    }
  ],
  "created_at": "2025-02-01T12:00:00Z",
  "updated_at": "2025-02-01T12:00:00Z"
}
The “Try It” feature is disabled because this endpoint requires a WebAuthn authenticator response. Use the Integration Guide for implementation examples.
Creates both a passkey account and a Grid smart account in a single atomic transaction. Pass the raw WebAuthn authenticatorResponse directly—the passkey does not need to exist beforehand.
This endpoint creates the passkey from your WebAuthn response. You do not need to call /passkeys/submit first.

What Gets Created

In one transaction:
  • Passkey account — derived from your WebAuthn public key
  • 1/1 smart account — with the passkey as sole signer (mask=7: full permissions)
  • Database records — GridUser, GridSmartAccount, and audit trail
  • 1 USDC funding — sandbox only

Implementation Flow (Direct API)

1

Generate Session Key

Create a Solana keypair for the session.
2

Get Current Slot

Fetch the current Solana slot number for replay protection.
3

Trigger WebAuthn

Call navigator.credentials.create() to create the passkey on the user’s device.
4

Call This Endpoint

Pass the raw authenticatorResponse to create both accounts atomically.
// After WebAuthn ceremony completes
const response = await fetch("/passkeys/account", {
  method: "POST",
  headers: {
    "Content-Type": "application/json",
    "Authorization": "Bearer YOUR_API_KEY",
    "x-grid-environment": "sandbox"
  },
  body: JSON.stringify({
    sessionKey: { key: sessionPublicKey, expiration: 900 },
    slotNumber: currentSlot,
    authenticatorResponse: credential.response  // raw WebAuthn response
  })
});

Timing Constraints

The slotNumber must be within Solana’s SlotHashes window (~3 minutes / 512 slots). If you encounter slot-related errors, fetch a fresh slot and retry.
Environment Isolation: Smart accounts have different addresses in sandbox vs production. Never send funds to the wrong environment.
{
  "address": "5nPmK...smartAccountAddress",
  "type": "passkey",
  "status": "active",
  "policies": {
    "threshold": 1,
    "admin_address": null
  },
  "authentication": [
    {
      "provider": "passkey",
      "session": {
        "Passkey": {
          "passkey_account": "7xK2...passkeyAddress",
          "pubkey": "base58EncodedPublicKey",
          "relying_party_id": "grid.squads.xyz",
          "session_key": {
            "key": "sessionPublicKey",
            "expiration": 1706832000
          }
        }
      }
    }
  ],
  "created_at": "2025-02-01T12:00:00Z",
  "updated_at": "2025-02-01T12:00:00Z"
}

Authorizations

Authorization
string
header
required

Your Grid API key from the Grid Dashboard

Headers

x-grid-environment
string
required

Solana network environment (sandbox, devnet, mainnet)

Body

application/json
authenticatorResponse
object
required
sessionKey
object
required

Grid v1 API SessionKey type that supports backward-compatible deserialization from both raw bytes array (old format) and base58 string (new format). Always serializes to base58 string format.

slotNumber
integer<int64>
required
Required range: x >= 0
adminAddress
string | null
memo
string | null

Response

Smart account created successfully with passkey signer

address
string
required
authentication
object[]
required
created_at
string<date-time>
required
policies
object
required
status
string
required
type
string
required
updated_at
string<date-time>
required