Overview
This guide shows you how to validate brand names against trademark databases across multiple jurisdictions, helping businesses choose safe, available names. What you’ll build:- Real-time name availability checking
- Multi-jurisdiction validation (US, EU, UK)
- Visual risk indicators
- Detailed conflict analysis
- Nice class mapping from business descriptions
Use Case: Startup Naming Tool
You’re building a tool for entrepreneurs to validate their startup names before incorporating or filing trademarks.The Problem
Entrepreneurs often:- Choose names without checking trademarks
- Discover conflicts after incorporation
- Face expensive rebranding
- Don’t know which jurisdictions to check
- Waste time and money on unavailable names
The Solution
Validate brand names across multiple jurisdictions before committing to them.Step 1: Determine Relevant Trademark Classes
First, classify the business to determine which Nice classes are relevant.Copy
async function getRelevantClasses(businessDescription) {
const response = await fetch('https://api.signa.so/v1/analysis/classify', {
method: 'POST',
headers: {
'Authorization': `Bearer ${process.env.TRADEMARK_API_KEY}`,
'Content-Type': 'application/json'
},
body: JSON.stringify({
text: businessDescription
})
});
return await response.json();
}
Example Request
Copy
const classification = await getRelevantClasses(
'SaaS platform for workflow automation'
);
// Returns:
{
"suggested_classes": [
{
"class_number": 9,
"name": "Computer software",
"reason": "Software products and downloadable applications",
"confidence": 0.92
},
{
"class_number": 42,
"name": "Software as a service (SaaS)",
"reason": "Cloud-based software services",
"confidence": 0.95
}
]
}
Step 2: Check Brand Name in Those Classes
Now run the fast conflict check with the brand name and relevant classes.Copy
async function checkBrandName(name, classes, jurisdictions = ['US', 'EU', 'UK']) {
const response = await fetch('https://api.signa.so/v1/analysis/check', {
method: 'POST',
headers: {
'Authorization': `Bearer ${process.env.TRADEMARK_API_KEY}`,
'Content-Type': 'application/json'
},
body: JSON.stringify({
text: name,
classes: classes,
jurisdictions: jurisdictions
})
});
return await response.json();
}
Example Request
Copy
// First, get classes
const classification = await getRelevantClasses('SaaS platform for workflow automation');
const classes = classification.suggested_classes.map(c => c.class_number); // [9, 42]
// Then check the brand name
const result = await checkBrandName('CloudFlow', classes);
Example Response
Copy
{
"risk_level": "MEDIUM",
"risk_score": 0.58,
"conflicts_by_jurisdiction": {
"US": {
"conflict_count": 3,
"highest_risk": 0.72,
"conflicts": [
{
"mark": {
"text": "CLOUDFLOW",
"id": "tm_us_1234567"
},
"similarity_score": 0.98,
"status": "live_registered",
"classes": [42],
"owner": "CloudFlow Technologies Inc.",
"reason": "Exact match in Class 42 (SaaS services)"
}
]
},
"EU": {
"conflict_count": 1,
"highest_risk": 0.45,
"conflicts": []
},
"UK": {
"conflict_count": 0,
"highest_risk": 0.0,
"conflicts": []
}
},
"recommendation": "HIGH_RISK_IN_US",
"analysis_time_ms": 542
}
Step 3: Display Risk Levels
Show clear visual indicators for each jurisdiction.Copy
function getRiskIndicator(riskLevel) {
const indicators = {
'CLEAR': {
color: 'green',
icon: '✓',
label: 'Available',
description: 'No conflicts found',
canProceed: true
},
'LOW': {
color: 'blue',
icon: 'i',
label: 'Low Risk',
description: 'Minor similarities exist',
canProceed: true
},
'MEDIUM': {
color: 'orange',
icon: '⚠',
label: 'Moderate Risk',
description: 'Potential conflicts detected',
canProceed: false
},
'HIGH': {
color: 'red',
icon: '✕',
label: 'High Risk',
description: 'Strong conflicts found',
canProceed: false
}
};
return indicators[riskLevel];
}
UI Component
Copy
function BrandNameChecker() {
const [brandName, setBrandName] = useState('');
const [businessDesc, setBusinessDesc] = useState('');
const [result, setResult] = useState(null);
const [checking, setChecking] = useState(false);
async function validateName() {
if (brandName.length < 2) return;
setChecking(true);
const checkResult = await checkBrandName(brandName, businessDesc);
setResult(checkResult);
setChecking(false);
}
const indicator = result ? getRiskIndicator(result.risk_level) : null;
return (
<div className="brand-checker">
<h2>Check Brand Name Availability</h2>
<input
type="text"
value={brandName}
onChange={(e) => setBrandName(e.target.value)}
onBlur={validateName}
placeholder="Enter your brand name"
/>
<textarea
value={businessDesc}
onChange={(e) => setBusinessDesc(e.target.value)}
placeholder="Describe your business (e.g., SaaS platform for workflow automation)"
/>
<button onClick={validateName} disabled={checking}>
{checking ? 'Checking...' : 'Check Availability'}
</button>
{indicator && (
<div className={`result result-${indicator.color}`}>
<div className="risk-badge">
<span className="icon">{indicator.icon}</span>
<span className="label">{indicator.label}</span>
</div>
<p>{indicator.description}</p>
</div>
)}
</div>
);
}
Step 4: Multi-Jurisdiction Results
Display results for each jurisdiction separately.Copy
function JurisdictionResults({ conflictsByJurisdiction }) {
return (
<div className="jurisdiction-results">
<h3>Results by Jurisdiction</h3>
{Object.entries(conflictsByJurisdiction).map(([code, data]) => {
const jurisdictionNames = {
'US': 'United States',
'EU': 'European Union',
'UK': 'United Kingdom'
};
const riskLevel = data.highest_risk > 0.7 ? 'HIGH' :
data.highest_risk > 0.5 ? 'MEDIUM' :
data.highest_risk > 0.3 ? 'LOW' : 'CLEAR';
const indicator = getRiskIndicator(riskLevel);
return (
<div key={code} className={`jurisdiction-card ${indicator.color}`}>
<div className="jurisdiction-header">
<h4>{jurisdictionNames[code]}</h4>
<span className={`badge badge-${indicator.color}`}>
{indicator.icon} {indicator.label}
</span>
</div>
<div className="stats">
<span>{data.conflict_count} conflicts found</span>
{data.conflict_count > 0 && (
<span>Highest similarity: {(data.highest_risk * 100).toFixed(0)}%</span>
)}
</div>
{data.conflicts.length > 0 && (
<div className="conflicts">
<h5>Top Conflicts:</h5>
{data.conflicts.slice(0, 3).map(conflict => (
<div key={conflict.mark.id} className="conflict">
<strong>{conflict.mark.text}</strong>
<span className="similarity">
{(conflict.similarity_score * 100).toFixed(0)}% similar
</span>
<p className="reason">{conflict.reason}</p>
<small>Owner: {conflict.owner}</small>
</div>
))}
</div>
)}
</div>
);
})}
</div>
);
}
Step 5: Deep Clearance Analysis
For names that pass the fast check, offer detailed analysis.Copy
async function runDeepClearance(name, businessDesc) {
const response = await fetch('https://api.signa.so/v1/analysis/clearance', {
method: 'POST',
headers: {
'Authorization': `Bearer ${process.env.TRADEMARK_API_KEY}`,
'Content-Type': 'application/json'
},
body: JSON.stringify({
trademark: name,
business_description: businessDesc,
offices: ['USPTO', 'EUIPO', 'UKIPO']
})
});
return await response.json();
}
Deep Analysis UI
Copy
function DetailedAnalysis({ result }) {
const [deepAnalysis, setDeepAnalysis] = useState(null);
const [loading, setLoading] = useState(false);
async function runAnalysis() {
setLoading(true);
const analysis = await runDeepClearance(
result.brand_name,
result.business_description
);
setDeepAnalysis(analysis);
setLoading(false);
}
// Only show for CLEAR or LOW risk names
if (result.risk_level === 'HIGH' || result.risk_level === 'MEDIUM') {
return null;
}
return (
<div className="deep-analysis">
<h3>Get Detailed Clearance Report</h3>
<p>Run a comprehensive AI analysis with detailed recommendations.</p>
<button onClick={runAnalysis} disabled={loading}>
{loading ? 'Analyzing...' : 'Run Deep Analysis (5 credits)'}
</button>
{deepAnalysis && (
<div className="analysis-report">
<div className="risk-assessment">
<h4>Overall Risk Assessment</h4>
<div className={`risk-badge risk-${deepAnalysis.risk_level.toLowerCase()}`}>
{deepAnalysis.risk_level}
</div>
<p className="recommendation">{deepAnalysis.recommendation}</p>
</div>
<div className="suggested-classes">
<h4>Relevant Trademark Classes</h4>
{Object.entries(deepAnalysis.relevant_classes).map(([classNum, info]) => (
<div key={classNum} className="class-item">
<strong>Class {classNum}: {info.name}</strong>
<p>{info.reason}</p>
<span className="confidence">
Confidence: {(info.confidence * 100).toFixed(0)}%
</span>
</div>
))}
</div>
<div className="conflict-analysis">
<h4>Detailed Conflict Analysis</h4>
{deepAnalysis.conflicts.map(conflict => (
<div key={conflict.mark_id} className="conflict-detail">
<div className="conflict-header">
<h5>{conflict.mark_text}</h5>
<span className="risk-score">
Risk: {(conflict.risk_score * 100).toFixed(0)}%
</span>
</div>
<p className="conflict-reason">{conflict.conflict_reason}</p>
<div className="conflict-meta">
<span>Owner: {conflict.owner}</span>
<span>Status: {conflict.status}</span>
<span>Classes: {conflict.classes.join(', ')}</span>
</div>
</div>
))}
</div>
<div className="next-steps">
<h4>Next Steps</h4>
<ul>
{deepAnalysis.next_steps.map((step, i) => (
<li key={i}>{step}</li>
))}
</ul>
</div>
</div>
)}
</div>
);
}
Displaying Class Suggestions to Users
Show users which trademark classes are relevant to their business.Copy
function ClassSuggestions({ businessDesc }) {
const [classes, setClasses] = useState(null);
useEffect(() => {
if (businessDesc.length > 10) {
getClassSuggestions(businessDesc).then(setClasses);
}
}, [businessDesc]);
if (!classes) return null;
return (
<div className="class-suggestions">
<h4>Recommended Trademark Classes</h4>
<p>Based on your business description, you should check these classes:</p>
<div className="classes-list">
{classes.suggested_classes.map(cls => (
<div key={cls.class_number} className="class-card">
<div className="class-number">Class {cls.class_number}</div>
<div className="class-name">{cls.name}</div>
<p className="class-reason">{cls.reason}</p>
<div className="confidence-bar">
<div
className="confidence-fill"
style={{ width: `${cls.confidence * 100}%` }}
/>
<span>{(cls.confidence * 100).toFixed(0)}% match</span>
</div>
</div>
))}
</div>
</div>
);
}
Complete Example
Here’s a full working implementation:Copy
class BrandNameValidator {
constructor(apiKey) {
this.apiKey = apiKey;
this.baseUrl = 'https://api.signa.so/v1';
}
async checkAvailability(brandName, businessDescription, jurisdictions = ['US', 'EU', 'UK']) {
// 1. First, classify the business to get relevant Nice classes
const classification = await this.classify(businessDescription);
const classes = classification.suggested_classes.map(c => c.class_number);
// 2. Run fast conflict check with those classes
const fastCheck = await this.fastCheck(brandName, classes, jurisdictions);
// 3. Return results with class information
return {
brand_name: brandName,
risk_level: fastCheck.risk_level,
risk_score: fastCheck.risk_score,
conflicts_by_jurisdiction: fastCheck.conflicts_by_jurisdiction,
suggested_classes: classification.suggested_classes,
recommendation: this.getRecommendation(fastCheck),
can_proceed: fastCheck.risk_level === 'CLEAR' || fastCheck.risk_level === 'LOW'
};
}
async classify(businessDescription) {
const response = await fetch(`${this.baseUrl}/analysis/classify`, {
method: 'POST',
headers: {
'Authorization': `Bearer ${this.apiKey}`,
'Content-Type': 'application/json'
},
body: JSON.stringify({ text: businessDescription })
});
return response.json();
}
async fastCheck(text, classes, jurisdictions) {
const response = await fetch(`${this.baseUrl}/analysis/check`, {
method: 'POST',
headers: {
'Authorization': `Bearer ${this.apiKey}`,
'Content-Type': 'application/json'
},
body: JSON.stringify({ text, classes, jurisdictions })
});
return response.json();
}
async deepClearance(trademark, businessDescription) {
const response = await fetch(`${this.baseUrl}/analysis/clearance`, {
method: 'POST',
headers: {
'Authorization': `Bearer ${this.apiKey}`,
'Content-Type': 'application/json'
},
body: JSON.stringify({
trademark,
business_description: businessDescription,
offices: ['USPTO', 'EUIPO', 'UKIPO']
})
});
return response.json();
}
getRecommendation(result) {
const hasHighRiskJurisdiction = Object.values(result.conflicts_by_jurisdiction)
.some(j => j.highest_risk > 0.7);
if (hasHighRiskJurisdiction) {
return 'HIGH_RISK - Choose a different name';
}
if (result.risk_level === 'MEDIUM') {
return 'MODERATE_RISK - Consider alternatives or run deep analysis';
}
if (result.risk_level === 'LOW') {
return 'LOW_RISK - Proceed with caution, review conflicts';
}
return 'CLEAR - Name appears available';
}
}
// Usage
const validator = new BrandNameValidator(process.env.TRADEMARK_API_KEY);
const result = await validator.checkAvailability(
'CloudFlow',
'SaaS platform for workflow automation and team collaboration'
);
console.log(`Risk Level: ${result.risk_level}`);
console.log(`Recommendation: ${result.recommendation}`);
console.log(`Can proceed: ${result.can_proceed}`);
// If low risk, get detailed analysis
if (result.can_proceed) {
const deepAnalysis = await validator.deepClearance(
'CloudFlow',
'SaaS platform for workflow automation and team collaboration'
);
console.log('Detailed analysis:', deepAnalysis);
}
Real-World Examples
Example 1: Available Name
Copy
// Input
{
brandName: "Streamline",
businessDescription: "Project management software for remote teams"
}
// Fast Check Result
{
risk_level: "CLEAR",
conflicts_by_jurisdiction: {
"US": { conflict_count: 0 },
"EU": { conflict_count: 0 },
"UK": { conflict_count: 0 }
},
recommendation: "CLEAR - Name appears available"
}
// ✓ Safe to proceed
Example 2: Low Risk Name
Copy
// Input
{
brandName: "SwiftTask",
businessDescription: "Task management app for developers"
}
// Fast Check Result
{
risk_level: "LOW",
conflicts_by_jurisdiction: {
"US": {
conflict_count: 2,
highest_risk: 0.42,
conflicts: [
{
mark: "SWIFTTASKS",
similarity_score: 0.42,
reason: "Similar but different overall impression"
}
]
}
},
recommendation: "LOW_RISK - Proceed with caution"
}
// ⚠ Review conflicts but can proceed
Example 3: High Risk Name
Copy
// Input
{
brandName: "Microsoft Flow",
businessDescription: "Workflow automation platform"
}
// Fast Check Result
{
risk_level: "HIGH",
conflicts_by_jurisdiction: {
"US": {
conflict_count: 1,
highest_risk: 0.98,
conflicts: [
{
mark: "MICROSOFT POWER AUTOMATE (FLOW)",
similarity_score: 0.98,
owner: "Microsoft Corporation",
status: "live_registered",
reason: "Exact match with famous registered trademark"
}
]
}
},
recommendation: "HIGH_RISK - Choose a different name"
}
// ✗ Do not use
Best Practices
Validate on Blur
Don’t check on every keystroke - wait until user finishes typing:Copy
<input
value={brandName}
onChange={(e) => setBrandName(e.target.value)}
onBlur={() => validateName()} // Check when user leaves field
/>
Cache Results
Cache checks for 24 hours to avoid redundant API calls:Copy
const cache = new Map();
async function validateWithCache(name, desc) {
const key = `${name.toLowerCase()}:${desc}`;
if (cache.has(key)) {
return cache.get(key);
}
const result = await checkBrandName(name, desc);
cache.set(key, result);
return result;
}
Progressive Disclosure
Show deep analysis only for promising names:Copy
// Only offer deep analysis for CLEAR or LOW risk
if (result.risk_level === 'CLEAR' || result.risk_level === 'LOW') {
showDeepAnalysisButton();
}
Cost Analysis
For a naming agency checking 50 names/month:- Classification (get Nice classes): 50 × 1 credit = 50 credits
- Fast conflict checks: 50 × 2 credits = 100 credits
- Deep analysis (10 promising names): 10 × 5 credits = 50 credits
- Total: 200 credits/month
Next Steps
API Reference
View complete API documentation
Analysis Endpoints
Explore analysis features
Product Listing Guide
Check product names for e-commerce
Rate Limits
Understand credit usage