Skip to main content
GET
https://api-mainnet.onzks.com
/
v1
/
identity
/
check
/
:name
Check Name Availability
curl --request GET \
  --url https://api-mainnet.onzks.com/v1/identity/check/:name \
  --header 'Authorization: Bearer <token>'
{
  "success": false,
  "error": "INVALID_NAME_FORMAT",
  "message": "Name must be 3-32 characters, lowercase letters, numbers, and hyphens only"
}

Overview

Check if a desired ZKS ID name is available before attempting to mint. This endpoint validates the name format and checks if it’s already taken. If unavailable, it provides alternative suggestions.
Always check availability before minting to avoid errors and provide a better user experience with name suggestions.

Parameters

name
string
required
The desired ZKS ID name to check (without .zks suffix). Must be 3-32 characters, lowercase letters, numbers, and hyphens only.

Response

success
boolean
Indicates if the request was successful
name
string
The name that was checked
available
boolean
Whether the name is available for minting
valid
boolean
Whether the name meets format requirements
reason
string
If unavailable or invalid, explains why
suggestions
array
Array of alternative name suggestions if the requested name is unavailable

Examples

curl https://api.onzks.com/v1/identity/check/alice \
  -H "Authorization: Bearer YOUR_API_KEY"

Response Examples

Available Name

{
  "success": true,
  "name": "alice",
  "available": true,
  "valid": true
}

Unavailable Name (Taken)

{
  "success": true,
  "name": "john",
  "available": false,
  "valid": true,
  "reason": "Name is already taken",
  "suggestions": [
    "john1",
    "john-zk",
    "john2024",
    "john-defi",
    "johndoe"
  ]
}

Invalid Name Format

{
  "success": true,
  "name": "al",
  "available": false,
  "valid": false,
  "reason": "Name must be at least 3 characters long",
  "suggestions": [
    "alice",
    "alex",
    "alan"
  ]
}

Invalid Characters

{
  "success": true,
  "name": "Alice",
  "available": false,
  "valid": false,
  "reason": "Name must contain only lowercase letters, numbers, and hyphens",
  "suggestions": [
    "alice",
    "alice1",
    "alice-zk"
  ]
}

Validation Rules

Valid Name Requirements

  • Length: 3-32 characters (excluding .zks suffix)
  • Characters: Lowercase letters (a-z), numbers (0-9), hyphens (-)
  • Start/End: Must start and end with a letter or number (not hyphen)
  • No consecutive hyphens: Cannot have multiple hyphens in a row

Examples

NameValidReason
alicePerfect
defi-masterValid with hyphen
user123Valid with numbers
alToo short (min 3)
AliceContains uppercase
-aliceStarts with hyphen
alice-Ends with hyphen
alice--bobConsecutive hyphens
alice.ethContains period
this-name-is-way-too-long-for-validationToo long (max 32)

Use Cases

1. Real-time Name Validation

Check availability as user types:
let checkTimeout;

function onNameInput(name) {
  // Debounce API calls
  clearTimeout(checkTimeout);
  
  checkTimeout = setTimeout(async () => {
    const result = await checkNameAvailability(name);
    
    if (result.available) {
      showSuccess(`${name}.zks is available!`);
    } else {
      showError(`${name}.zks is taken`);
      showSuggestions(result.suggestions);
    }
  }, 500); // Wait 500ms after user stops typing
}

2. Name Suggestion Flow

Provide alternatives if name is taken:
async function findAvailableName(desiredName) {
  let result = await checkNameAvailability(desiredName);
  
  if (result.available) {
    return desiredName;
  }
  
  // Try suggestions
  for (const suggestion of result.suggestions) {
    result = await checkNameAvailability(suggestion);
    
    if (result.available) {
      console.log(`${desiredName} is taken, using ${suggestion} instead`);
      return suggestion;
    }
  }
  
  // Generate custom suggestion
  const customName = `${desiredName}${Math.floor(Math.random() * 1000)}`;
  return customName;
}

3. Batch Name Checking

Check multiple names at once:
async function checkMultipleNames(names) {
  const results = await Promise.all(
    names.map(name => checkNameAvailability(name))
  );
  
  const available = results
    .filter(r => r.available)
    .map(r => r.name);
  
  const taken = results
    .filter(r => !r.available)
    .map(r => r.name);
  
  return { available, taken };
}

// Usage
const { available, taken } = await checkMultipleNames([
  'alice', 'bob', 'charlie', 'david'
]);

console.log('Available:', available);
console.log('Taken:', taken);

4. Smart Suggestions

Generate intelligent name suggestions:
async function getSmartSuggestions(baseName) {
  const result = await checkNameAvailability(baseName);
  
  if (result.available) {
    return [baseName];
  }
  
  // Try API suggestions first
  const suggestions = [...result.suggestions];
  
  // Add custom suggestions
  suggestions.push(
    `${baseName}-defi`,
    `${baseName}-nft`,
    `${baseName}${new Date().getFullYear()}`,
    `${baseName}-trader`,
    `${baseName}-dev`
  );
  
  // Check which suggestions are available
  const availableSuggestions = [];
  
  for (const suggestion of suggestions) {
    const check = await checkNameAvailability(suggestion);
    if (check.available) {
      availableSuggestions.push(suggestion);
    }
    
    // Limit to 5 suggestions
    if (availableSuggestions.length >= 5) break;
  }
  
  return availableSuggestions;
}

Best Practices

1. Debounce API Calls

Avoid excessive API calls during typing:
import { debounce } from 'lodash';

const checkAvailability = debounce(async (name) => {
  const result = await fetch(`/v1/identity/check/${name}`);
  return result.json();
}, 500);

2. Cache Results

Cache availability checks to reduce API calls:
const availabilityCache = new Map();

async function checkWithCache(name) {
  if (availabilityCache.has(name)) {
    return availabilityCache.get(name);
  }
  
  const result = await checkNameAvailability(name);
  availabilityCache.set(name, result);
  
  // Clear cache after 5 minutes
  setTimeout(() => availabilityCache.delete(name), 5 * 60 * 1000);
  
  return result;
}

3. Validate Locally First

Check format locally before API call:
function isValidNameFormat(name) {
  // Check length
  if (name.length < 3 || name.length > 32) {
    return { valid: false, reason: 'Length must be 3-32 characters' };
  }
  
  // Check characters
  if (!/^[a-z0-9-]+$/.test(name)) {
    return { valid: false, reason: 'Only lowercase letters, numbers, and hyphens' };
  }
  
  // Check start/end
  if (name.startsWith('-') || name.endsWith('-')) {
    return { valid: false, reason: 'Cannot start or end with hyphen' };
  }
  
  // Check consecutive hyphens
  if (name.includes('--')) {
    return { valid: false, reason: 'Cannot have consecutive hyphens' };
  }
  
  return { valid: true };
}

// Use before API call
const validation = isValidNameFormat(name);
if (!validation.valid) {
  showError(validation.reason);
  return;
}

// Only call API if format is valid
const result = await checkNameAvailability(name);

4. Show Real-time Feedback

Provide immediate visual feedback:
async function validateNameInput(inputElement) {
  const name = inputElement.value.toLowerCase();
  
  // Local validation
  const validation = isValidNameFormat(name);
  if (!validation.valid) {
    inputElement.classList.add('invalid');
    showError(validation.reason);
    return;
  }
  
  // API check
  const result = await checkNameAvailability(name);
  
  if (result.available) {
    inputElement.classList.add('valid');
    inputElement.classList.remove('invalid');
    showSuccess(`${name}.zks is available!`);
  } else {
    inputElement.classList.add('invalid');
    inputElement.classList.remove('valid');
    showSuggestions(result.suggestions);
  }
}

Error Responses

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

Integration Example

Complete name selection flow:
class NameSelector {
  constructor(apiKey) {
    this.apiKey = apiKey;
    this.cache = new Map();
  }

  async checkAvailability(name) {
    // Validate format
    const validation = this.validateFormat(name);
    if (!validation.valid) {
      return validation;
    }

    // Check cache
    if (this.cache.has(name)) {
      return this.cache.get(name);
    }

    // API call
    const response = await fetch(
      `https://api.onzks.com/v1/identity/check/${name}`,
      { headers: { 'Authorization': `Bearer ${this.apiKey}` } }
    );

    const result = await response.json();
    this.cache.set(name, result);

    return result;
  }

  validateFormat(name) {
    if (name.length < 3 || name.length > 32) {
      return { 
        valid: false, 
        available: false,
        reason: 'Length must be 3-32 characters' 
      };
    }

    if (!/^[a-z0-9-]+$/.test(name)) {
      return { 
        valid: false, 
        available: false,
        reason: 'Only lowercase letters, numbers, and hyphens' 
      };
    }

    if (name.startsWith('-') || name.endsWith('-')) {
      return { 
        valid: false, 
        available: false,
        reason: 'Cannot start or end with hyphen' 
      };
    }

    return { valid: true };
  }

  async getSuggestions(baseName) {
    const result = await this.checkAvailability(baseName);
    
    if (result.available) {
      return [baseName];
    }

    return result.suggestions || [];
  }
}

// Usage
const selector = new NameSelector('YOUR_API_KEY');
const result = await selector.checkAvailability('alice');

if (result.available) {
  console.log('Name is available!');
} else {
  const suggestions = await selector.getSuggestions('alice');
  console.log('Try these:', suggestions);
}

Troubleshooting

”Too many requests”

Cause: Exceeded rate limits for availability checks. Solution:
  • Implement debouncing (wait 500ms after user stops typing)
  • Cache results locally
  • Reduce frequency of checks

”Invalid name format”

Cause: Name doesn’t meet validation requirements. Solution:
  • Validate locally before API call
  • Show clear validation rules to users
  • Provide real-time format feedback

Rate Limits

Name availability checks are subject to rate limits:
  • Free tier: 100 checks per minute
  • Starter tier: 500 checks per minute
  • Professional tier: 2,000 checks per minute
  • Enterprise tier: Custom limits
Implement debouncing and caching to stay within limits.