Skip to main content

Common Issues

Bad Request (400 Error)

Symptoms:
try {
  await client.brand.retrieve({ domain: "invalid" });
} catch (error) {
  if (error.status === 400) {
    console.error("Bad request:", error.message);
  }
}
Possible Causes:
  1. Invalid domain format
    • Don’t include protocol (https://) or subdomain (www.)
    • Use stripe.com not www.stripe.com or https://stripe.com
  2. Missing required parameters
    • Check that all required fields are included in your request
  3. Invalid parameter values
    • Company name must be 3-30 characters for /brand/retrieve-by-name
    • Email must be valid format for /brand/retrieve-by-email
Solutions:
// ✅ Correct format
await client.brand.retrieve({ domain: "stripe.com" });

// ❌ Incorrect formats
await client.brand.retrieve({ domain: "https://stripe.com" }); // No protocol
await client.brand.retrieve({ domain: "www.stripe.com" }); // No subdomain
await client.brand.retrieve({ domain: "stripe" }); // Need full domain
If the domain format is correct but you’re still getting errors, contact support for assistance.

Invalid API Key (401 Error)

Symptoms:
try {
  await client.brand.retrieve({ domain: "stripe.com" });
} catch (error) {
  if (error.status === 401) {
    console.error("Invalid API key");
  }
}
Possible Causes:
  1. Missing API key in request
  2. Incorrect API key value
  3. API key has been deleted or expired
  4. API key not properly loaded from environment variables
Solutions:
// Add debug logging (remove after fixing)
console.log("API Key exists:", !!process.env.BRAND_DEV_API_KEY);
console.log("API Key length:", process.env.BRAND_DEV_API_KEY?.length);
// DO NOT log the actual key value!

const client = new BrandDev({
  apiKey: process.env.BRAND_DEV_API_KEY,
});
// Make sure the variable name matches exactly
// Common mistakes:
process.env.BRANDDEV_API_KEY; // ❌ Missing underscore
process.env.BRAND_DEV_APIKEY; // ❌ Missing underscore
process.env.BRAND_DEV_API_KEY; // ✅ Correct
// Node.js with dotenv
import "dotenv/config"; // Must be at the top of your file

// Or
import dotenv from "dotenv";
dotenv.config();

const client = new BrandDev({
  apiKey: process.env.BRAND_DEV_API_KEY,
});
If your key is compromised or deleted:
  1. Log in to brand.dev
  2. Navigate to API Keys
  3. Generate a new key
  4. Update your environment variables
  5. Restart your application

Request Timeout (408 Error)

Symptoms:
try {
  await client.brand.retrieve({ domain: "example.com", timeoutMS: 5000 });
} catch (error) {
  if (error.status === 408) {
    console.error("Request timed out");
  }
}
Possible Causes:
  1. Custom timeoutMS parameter set too low
  2. Cold hit taking longer than expected (first request for a domain)
  3. Network latency issues
Understanding the timeoutMS Parameter: You can optionally set a custom timeout using the timeoutMS parameter:
  • Minimum: 1ms
  • Maximum: 300000ms (5 minutes)
  • If the request exceeds this timeout, it will be aborted with a 408 status code
Solutions:
// For cold hits, allow more time (up to 5 minutes max)
const { brand } = await client.brand.retrieve({
  domain: "example.com",
  timeoutMS: 60000, // 60 seconds
});

// For time-sensitive operations, use a shorter timeout
const { brand } = await client.brand.retrieve({
  domain: "stripe.com",
  timeoutMS: 10000, // 10 seconds
});
Prefetch brand data before you need it (available on paid plans):
// When user enters email, prefetch immediately
async function handleEmailInput(email: string) {
  if (email.includes("@")) {
    const domain = email.split("@")[1];

    // Fire and forget - doesn't charge credits
    client.utility.prefetch({ domain }).catch(() => {});
  }
}

// Later, when you need the data, it's cached and fast
const { brand } = await client.brand.retrieve({ domain });
// Enable fast mode for quicker responses (less comprehensive data)
const { brand } = await client.brand.retrieve({
  domain: "example.com",
  fast: true,
});
async function fetchWithRetry(domain: string, maxRetries = 3) {
  for (let i = 0; i < maxRetries; i++) {
    try {
      return await client.brand.retrieve({ domain });
    } catch (error) {
      if (error.status === 408 && i < maxRetries - 1) {
        const delay = Math.pow(2, i) * 1000; // Exponential backoff
        await new Promise((resolve) => setTimeout(resolve, delay));
        continue;
      }
      throw error;
    }
  }
}
const brandCache = new Map<string, { data: any; timestamp: number }>();
const CACHE_TTL = 24 * 60 * 60 * 1000; // 24 hours

async function getBrandCached(domain: string) {
  const cached = brandCache.get(domain);

  if (cached && Date.now() - cached.timestamp < CACHE_TTL) {
    return cached.data;
  }

  const { brand } = await client.brand.retrieve({ domain });
  brandCache.set(domain, { data: brand, timestamp: Date.now() });
  return brand;
}

Slow Response Times

Symptoms:
  • Requests taking longer than expected
  • Timeouts on cold hits
Understanding Response Times:
  • Warm hits (cached): ~250ms (p50)
  • Cold hits (first request): ~7 seconds (p50), up to 30 seconds (p99)
Use the fast parameter to optimize for speed at the cost of less comprehensive data. Use timeoutMS to set a custom timeout (max 300,000ms / 5 minutes).
Solutions:
Prefetch brand data as early as possible:
// When user enters email, prefetch immediately
async function handleEmailInput(email: string) {
  if (email.includes("@")) {
    const domain = email.split("@")[1];

    // Fire and forget - doesn't count against credits
    client.utility.prefetchByEmail({ email }).catch(() => {
      // Silently fail - the main retrieve will still work
    });
  }
}

// Later, when you need the data, it's cached
async function loadUserProfile(email: string) {
  const domain = email.split("@")[1];
  const { brand } = await client.brand.retrieve({ domain }); // Fast!
  // ... use brand data
}
Show proper loading UI for cold hits:
async function loadBrandData(domain: string) {
  try {
    // Show loading state
    setLoading(true);
    setLoadingMessage("Fetching brand data...");

    const { brand } = await client.brand.retrieve({ domain });

    setLoading(false);
    return brand;
  } catch (error) {
    setLoading(false);
    setError(error.message);
  }
}
// Allow enough time for cold hits
const client = new BrandDev({
  apiKey: process.env.BRAND_DEV_API_KEY,
  timeout: 35000, // 35 seconds to account for p99
});
For non-critical use cases, fetch data asynchronously:
// Queue for background processing
async function enrichLeadInBackground(leadId: string, domain: string) {
  try {
    const { brand } = await client.brand.retrieve({ domain });

    // Update lead in database when ready
    await database.leads.update(leadId, {
      brand_data: brand,
      enriched_at: new Date(),
    });
  } catch (error) {
    console.error(`Failed to enrich lead ${leadId}:`, error);
  }
}

// Don't await - process in background
enrichLeadInBackground(lead.id, lead.domain);

Invalid Email (422 Error)

This error only applies to the /brand/retrieve-by-email endpoint.
Symptoms:
try {
  await client.brand.retrieveByEmail({ email: "[email protected]" });
} catch (error) {
  if (error.status === 422) {
    console.error("Invalid email:", error.message);
    // e.g., "Disposable or free email provider"
  }
}
Possible Causes:
  1. Disposable/temporary email service (e.g., tempmail.com, guerrillamail.com)
  2. Free email provider (e.g., gmail.com, yahoo.com, hotmail.com, outlook.com)
  3. Invalid email format
Solutions:
// Validate before sending to API
function isDomainBrandable(email: string): boolean {
  const domain = email.split("@")[1]?.toLowerCase();

  const freeProviders = [
    "gmail.com",
    "yahoo.com",
    "hotmail.com",
    "outlook.com",
    "aol.com",
    "icloud.com",
    "protonmail.com",
  ];

  return domain && !freeProviders.includes(domain);
}

// Only call API for brandable domains
if (isDomainBrandable(email)) {
  await client.brand.retrieve({ domain: email.split("@")[1] });
} else {
  // Skip brand enrichment for free email providers
  console.log("Skipping brand data for free email provider");
}

Server Error (500 Error)

Symptoms:
try {
  await client.brand.retrieveByEmail({ email: "[email protected]" });
} catch (error) {
  if (error.status === 500) {
    console.error("Server error - please retry");
  }
}
Possible Causes:
  1. Temporary server issue
  2. Unexpected data format from source
  3. Internal processing error
Solutions:
async function fetchWithRetry(domain: string, maxRetries = 3) {
  for (let i = 0; i < maxRetries; i++) {
    try {
      return await client.brand.retrieve({ domain });
    } catch (error) {
      if (error.status === 500 && i < maxRetries - 1) {
        const delay = Math.pow(2, i) * 1000; // Exponential backoff
        await new Promise((resolve) => setTimeout(resolve, delay));
        continue;
      }
      throw error;
    }
  }
}
If one endpoint fails, try using a different lookup method:
async function getBrandWithFallback(email: string) {
  try {
    // Try email endpoint first
    return await client.brand.retrieveByEmail({ email });
  } catch (error) {
    if (error.status === 500) {
      // Fall back to domain endpoint
      const domain = email.split("@")[1];
      return await client.brand.retrieve({ domain });
    }
    throw error;
  }
}
If you’re seeing consistent 500 errors:
  1. Check the status page for known issues
  2. Contact support with request details
  3. Include the domain/email, timestamp, and error message

Missing or Incomplete Brand Data

Symptoms:
  • API returns 200 but some fields are null or empty
  • Logos array is empty
  • Colors array is empty
Explanation: Not all brands have all data fields. Brand.dev returns what’s available from verified sources. Solutions:
function getBrandLogo(brand: Brand): string {
  // Try to get best logo
  const logo = brand.logos?.[0]?.url;

  // Fallback to generated avatar if no logo
  if (!logo) {
    return generateInitialsAvatar(brand.title || "Company");
  }

  return logo;
}

function getBrandColor(brand: Brand): string {
  // Try to get primary color
  const primaryColor = brand.colors?.[0]?.hex;

  // Fallback to neutral color
  return primaryColor || "#6B7280";
}
// Show brand data when available, generic UI when not
function CompanyProfile({ brand }: { brand: Brand }) {
  return (
    <div>
      {brand.logos?.[0] ? (
        <img src={brand.logos[0].url} alt={brand.title} />
      ) : (
        <div className="avatar">
          {brand.title?.charAt(0) || '?'}
        </div>
      )}

      <h1>{brand.title || 'Company'}</h1>

      {brand.description && (
        <p>{brand.description}</p>
      )}

      {brand.colors?.length > 0 && (
        <div className="color-palette">
          {brand.colors.map(color => (
            <div
              key={color.hex}
              style={{ backgroundColor: color.hex }}
              title={color.name}
            />
          ))}
        </div>
      )}
    </div>
  );
}
If a major brand is missing critical data, report it to improve our database:
// Report missing data
if (!brand.logos?.length) {
  fetch("https://brand.dev/api/report-missing-data", {
    method: "POST",
    headers: { "Content-Type": "application/json" },
    body: JSON.stringify({
      domain: brand.domain,
      missing_field: "logos",
    }),
  });
}

SDK-Specific Issues

TypeScript Type Errors

Issue: Type errors with SDK responses Solution:
import BrandDev from "brand.dev";

// Use proper types
const client = new BrandDev({
  apiKey: process.env.BRAND_DEV_API_KEY!,
});

// Type the response
const response: BrandDev.BrandRetrieveResponse = await client.brand.retrieve({
  domain: "stripe.com",
});

// Access with autocomplete
const logo: string | undefined = response.brand.logos?.[0]?.url;

Python Import Errors

Issue: ModuleNotFoundError: No module named 'brand_dev' Solution:
# Reinstall the package
pip uninstall brand.dev
pip install brand.dev

# Or use pip3 on some systems
pip3 install brand.dev

# Verify installation
pip list | grep brand

Ruby Gem Installation Issues

Issue: Gem won’t install or load Solution:
# Update bundler
gem update bundler

# Clear gem cache
gem cleanup

# Reinstall
gem uninstall brand.dev
gem install brand.dev

# Or with bundle
bundle update brand.dev

Debugging Tips

Enable Debug Logging

// Enable debug mode (if supported by SDK)
const client = new BrandDev({
  apiKey: process.env.BRAND_DEV_API_KEY,
  // maxRetries: 3,
  // timeout: 30000,
});

// Log requests and responses
client.brand
  .retrieve({ domain: "stripe.com" })
  .then((response) => console.log("Success:", response))
  .catch((error) => console.error("Error:", error.status, error.message));

Test with cURL

Isolate issues by testing with raw HTTP requests:
curl https://api.brand.dev/v1/brand/retrieve \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"domain": "stripe.com"}' \
  -v  # Verbose output

Still Need Help?

If you’re still experiencing issues after trying these solutions:
When contacting support, please include: - The domain you’re trying to retrieve - Full error message and status code - SDK version and language - Timestamp of the request - Any relevant code snippets