Skip to main content
POST
https://api-mainnet.onzks.com
/
v1
/
identity
/
mint
Mint Identity
curl --request POST \
  --url https://api-mainnet.onzks.com/v1/identity/mint \
  --header 'Authorization: Bearer <token>' \
  --header 'Content-Type: application/json' \
  --data '
{
  "name": "<string>",
  "walletAddress": "<string>",
  "metadata": {
    "avatar": "<string>",
    "bio": "<string>",
    "socialLinks": {}
  }
}
'
{
  "success": false,
  "error": "INVALID_NAME_FORMAT",
  "message": "Name must be 3-32 characters, lowercase letters, numbers, and hyphens only"
}

Overview

Mint a new identity NFT (SBT) with a unique ZKS ID. This creates a non-transferable identity token that can be activated to become soulbound. Once minted, the identity can be used across the ZKScore ecosystem.
Identity names must be unique across the platform. Use the Check Availability endpoint to verify name availability before minting.

Request Body

name
string
required
The desired ZKS ID name (without .zks suffix). Must be 3-32 characters, lowercase letters, numbers, and hyphens only. Cannot start or end with a hyphen.
walletAddress
string
required
The Ethereum wallet address that will own this identity. Must be a valid address format.
metadata
object
Optional metadata for the identity

Response

success
boolean
Indicates if the minting was successful
identity
object

Examples

curl -X POST https://api.onzks.com/v1/identity/mint \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "alice",
    "walletAddress": "0x742d35Cc6635C0532925a3b844D1FF4e1321",
    "metadata": {
      "avatar": "https://example.com/avatar.png",
      "bio": "DeFi enthusiast and protocol researcher"
    }
  }'

Response Example

{
  "success": true,
  "identity": {
    "tokenId": 12345,
    "name": "alice",
    "ownerAddress": "0x742d35cc6635c0532925a3b844d1ff4e1321",
    "isActivated": false,
    "createdAt": "2024-01-15T10:30:00Z",
    "transactionHash": "0xabc123..."
  }
}

Error Responses

{
  "success": false,
  "error": "INVALID_NAME_FORMAT",
  "message": "Name must be 3-32 characters, lowercase letters, numbers, and hyphens only"
}

Name Validation Rules

Valid Names

Accepted formats:
  • alice - Simple name
  • defi-master - With hyphen
  • user123 - With numbers
  • my-identity-2024 - Multiple hyphens and numbers

Invalid Names

Rejected formats:
  • al - Too short (minimum 3 characters)
  • -alice - Starts with hyphen
  • alice- - Ends with hyphen
  • Alice - Contains uppercase
  • alice.eth - Contains period
  • alice@zks - Contains special characters
  • this-name-is-way-too-long-to-be-valid - Too long (maximum 32 characters)

Use Cases

1. User Onboarding

Create an identity during user registration:
async function onboardUser(walletAddress, desiredName) {
  try {
    // Check availability first
    const available = await checkAvailability(desiredName);
    
    if (!available) {
      throw new Error('Name not available');
    }

    // Mint identity
    const identity = await mintIdentity({
      name: desiredName,
      walletAddress: walletAddress
    });

    console.log(`Identity created: ${identity.name}.zks`);
    return identity;
  } catch (error) {
    console.error('Onboarding failed:', error);
    throw error;
  }
}

2. Batch Identity Creation

Create multiple identities for a team or organization:
async function createTeamIdentities(teamMembers) {
  const identities = [];
  
  for (const member of teamMembers) {
    const identity = await mintIdentity({
      name: member.username,
      walletAddress: member.address,
      metadata: {
        bio: member.role,
        socialLinks: member.socials
      }
    });
    
    identities.push(identity);
    
    // Rate limiting: wait 1 second between requests
    await new Promise(resolve => setTimeout(resolve, 1000));
  }
  
  return identities;
}

3. Identity with Custom Metadata

Create an identity with rich metadata:
const identity = await mintIdentity({
  name: 'defi-trader',
  walletAddress: '0x742d35Cc6635C0532925a3b844D1FF4e1321',
  metadata: {
    avatar: 'https://cdn.example.com/avatars/trader.png',
    bio: 'Professional DeFi trader specializing in yield farming',
    socialLinks: {
      twitter: 'https://twitter.com/defitrader',
      github: 'https://github.com/defitrader',
      discord: 'defitrader#1234'
    }
  }
});

Best Practices

1. Check Availability First

Always check name availability before attempting to mint:
const available = await checkAvailability('alice');
if (available) {
  await mintIdentity({ name: 'alice', walletAddress: address });
}

2. Handle Errors Gracefully

Provide helpful feedback when minting fails:
try {
  const identity = await mintIdentity({ name, walletAddress });
} catch (error) {
  if (error.code === 'NAME_ALREADY_TAKEN') {
    // Show suggestions to user
    console.log('Try these names:', error.suggestions);
  } else if (error.code === 'INVALID_NAME_FORMAT') {
    // Show validation rules
    console.log('Name must be 3-32 characters, lowercase only');
  }
}

3. Store Transaction Hash

Save the transaction hash for verification:
const identity = await mintIdentity({ name, walletAddress });
await database.save({
  userId: user.id,
  tokenId: identity.tokenId,
  transactionHash: identity.transactionHash,
  createdAt: identity.createdAt
});

4. Activate After Minting

Remember to activate the identity to make it soulbound:
// Step 1: Mint
const identity = await mintIdentity({ name, walletAddress });

// Step 2: Activate (makes it soulbound)
await activateIdentity({ tokenId: identity.tokenId });

Next Steps

After minting an identity:
  1. Activate Identity - Make the identity soulbound
  2. Get Identity - Retrieve identity information
  3. Get Score - Check the user’s ZKScore

Troubleshooting

”Name already taken”

Cause: The requested name is already registered by another user. Solution:
  • Use the suggestions provided in the error response
  • Try a different name with numbers or hyphens
  • Check availability before minting

”Invalid name format”

Cause: The name doesn’t meet validation requirements. Solution:
  • Ensure name is 3-32 characters
  • Use only lowercase letters, numbers, and hyphens
  • Don’t start or end with a hyphen

”Transaction failed”

Cause: Blockchain transaction failed or was reverted. Solution:
  • Check wallet has sufficient gas
  • Verify wallet address is correct
  • Try again after a few minutes
  • Contact support if issue persists

Rate Limits

Identity minting is subject to rate limits:
  • Free tier: 10 mints per hour
  • Starter tier: 100 mints per hour
  • Professional tier: 1,000 mints per hour
  • Enterprise tier: Custom limits
Exceeded rate limits will return a 429 Too Many Requests error.