> ## Documentation Index
> Fetch the complete documentation index at: https://docs.context.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# Troubleshooting

> Common issues and solutions when using the Context.dev API

<CardGroup cols={1}>
  <Card title="Check Status" icon="heart-pulse" href="https://status.context.dev">
    View system & API status
  </Card>
</CardGroup>

## Common Issues

### Bad Request (400 Error)

**Symptoms:**

<CodeGroup>
  ```typescript TypeScript theme={null}
  try {
    await client.brand.retrieve({ domain: "invalid" });
  } catch (error) {
    if (error.status === 400) {
      console.error("Bad request:", error.message);
    }
  }
  ```

  ```python Python theme={null}
  try:
      brand = client.brand.retrieve(domain="invalid")
  except context_dev.APIError as e:
      if e.status_code == 400:
          print(f"Bad request: {e.message}")
  ```
</CodeGroup>

**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:**

```typescript theme={null}
// 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](mailto:hello@context.dev) for assistance.

***

### Invalid API Key (401 Error)

**Symptoms:**

<CodeGroup>
  ```typescript TypeScript theme={null}
  try {
    await client.brand.retrieve({ domain: "stripe.com" });
  } catch (error) {
    if (error.status === 401) {
      console.error("Invalid API key");
    }
  }
  ```

  ```python Python theme={null}
  try:
      brand = client.brand.retrieve(domain="stripe.com")
  except context_dev.APIError as e:
      if e.status_code == 401:
          print("Invalid API key")
  ```

  ```ruby Ruby theme={null}
  begin
    brand = client.brand.retrieve(domain: 'stripe.com')
  rescue ContextDev::APIError => e
    if e.status == 401
      puts "Invalid API key"
    end
  end
  ```
</CodeGroup>

**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:**

<AccordionGroup>
  <Accordion title="Verify API key is loaded">
    ```typescript theme={null}
    // Add debug logging (remove after fixing)
    console.log("API Key exists:", !!process.env.CONTEXT_DEV_API_KEY);
    console.log("API Key length:", process.env.CONTEXT_DEV_API_KEY?.length);
    // DO NOT log the actual key value!

    const client = new ContextDev({
      apiKey: process.env.CONTEXT_DEV_API_KEY,
    });
    ```
  </Accordion>

  <Accordion title="Check environment variable naming">
    ```typescript theme={null}
    // Make sure the variable name matches exactly
    // Common mistakes:
    process.env.CONTEXTDEV_API_KEY; // Missing underscore
    process.env.CONTEXT_DEV_APIKEY; // Missing underscore
    process.env.CONTEXT_DEV_API_KEY; // Correct
    ```
  </Accordion>

  <Accordion title="Verify .env file is loaded">
    ```typescript theme={null}
    // 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 ContextDev({
      apiKey: process.env.CONTEXT_DEV_API_KEY,
    });
    ```
  </Accordion>

  <Accordion title="Get a new API key">
    If your key is compromised or deleted:

    1. Log in to [context.dev](https://context.dev)
    2. Navigate to API Keys
    3. Generate a new key
    4. Update your environment variables
    5. Restart your application
  </Accordion>
</AccordionGroup>

***

### Request Timeout (408 Error)

**Symptoms:**

<CodeGroup>
  ```typescript TypeScript theme={null}
  try {
    await client.brand.retrieve({ domain: "example.com", timeoutMS: 5000 });
  } catch (error) {
    if (error.status === 408) {
      console.error("Request timed out");
    }
  }
  ```

  ```python Python theme={null}
  try:
      brand = client.brand.retrieve(domain="example.com", timeout_ms=5000)
  except context_dev.APIError as e:
      if e.status_code == 408:
          print("Request timed out")
  ```
</CodeGroup>

**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:**

<AccordionGroup>
  <Accordion title="Set appropriate timeout values">
    ```typescript theme={null}
    // 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
    });
    ```
  </Accordion>

  <Accordion title="Use prefetching for better latency">
    Prefetch brand data before you need it (available on paid plans):

    ```typescript theme={null}
    // 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 });
    ```
  </Accordion>

  <Accordion title="Use fast mode for speed-optimized responses">
    ```typescript theme={null}
    // Enable fast mode for quicker responses (less comprehensive data)
    const { brand } = await client.brand.retrieve({
      domain: "example.com",
      fast: true,
    });
    ```
  </Accordion>

  <Accordion title="Implement retry with exponential backoff">
    ```typescript theme={null}
    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;
        }
      }
    }
    ```
  </Accordion>

  <Accordion title="Cache results client-side">
    ```typescript theme={null}
    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;
    }
    ```
  </Accordion>
</AccordionGroup>

***

### 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)

<Tip>
  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).
</Tip>

**Solutions:**

<AccordionGroup>
  <Accordion title="Use prefetching">
    Prefetch brand data as early as possible:

    ```typescript theme={null}
    // 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
    }
    ```
  </Accordion>

  <Accordion title="Implement loading states">
    Show proper loading UI for cold hits:

    ```typescript theme={null}
    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);
      }
    }
    ```
  </Accordion>

  <Accordion title="Set appropriate timeouts">
    ```typescript theme={null}
    // Allow enough time for cold hits
    const client = new ContextDev({
      apiKey: process.env.CONTEXT_DEV_API_KEY,
      timeout: 35000, // 35 seconds to account for p99
    });
    ```
  </Accordion>

  <Accordion title="Process in background">
    For non-critical use cases, fetch data asynchronously:

    ```typescript theme={null}
    // 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);
    ```
  </Accordion>
</AccordionGroup>

***

### Invalid Email (422 Error)

<Note>This error only applies to the `/brand/retrieve-by-email` endpoint.</Note>

**Symptoms:**

<CodeGroup>
  ```typescript TypeScript theme={null}
  try {
    await client.brand.retrieveByEmail({ email: "user@gmail.com" });
  } catch (error) {
    if (error.status === 422) {
      console.error("Invalid email:", error.message);
      // e.g., "Disposable or free email provider"
    }
  }
  ```

  ```python Python theme={null}
  try:
      brand = client.brand.retrieve_by_email(email="user@gmail.com")
  except context_dev.APIError as e:
      if e.status_code == 422:
          print(f"Invalid email: {e.message}")
  ```
</CodeGroup>

**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:**

```typescript theme={null}
// 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:**

<CodeGroup>
  ```typescript TypeScript theme={null}
  try {
    await client.brand.retrieveByEmail({ email: "user@company.com" });
  } catch (error) {
    if (error.status === 500) {
      console.error("Server error - please retry");
    }
  }
  ```

  ```python Python theme={null}
  try:
      brand = client.brand.retrieve_by_email(email="user@company.com")
  except context_dev.APIError as e:
      if e.status_code == 500:
          print("Server error - please retry")
  ```
</CodeGroup>

**Possible Causes:**

1. **Temporary server issue**
2. **Unexpected data format from source**
3. **Internal processing error**

**Solutions:**

<AccordionGroup>
  <Accordion title="Implement retry logic">
    ```typescript theme={null}
    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;
        }
      }
    }
    ```
  </Accordion>

  <Accordion title="Try an alternative endpoint">
    If one endpoint fails, try using a different lookup method:

    ```typescript theme={null}
    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;
      }
    }
    ```
  </Accordion>

  <Accordion title="Contact support for persistent issues">
    If you're seeing consistent 500 errors:

    1. Check the [status page](https://status.context.dev) for known issues
    2. [Contact support](mailto:hello@context.dev) with request details
    3. Include the domain/email, timestamp, and error message
  </Accordion>
</AccordionGroup>

***

### 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. Context.dev returns what's available from verified sources.

**Solutions:**

<AccordionGroup>
  <Accordion title="Always provide fallbacks">
    ```typescript theme={null}
    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";
    }
    ```
  </Accordion>

  <Accordion title="Graceful degradation">
    ```typescript theme={null}
    // 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>
      );
    }
    ```
  </Accordion>

  <Accordion title="Report missing data">
    If a major brand is missing critical data, report it to improve our database:

    ```typescript theme={null}
    // Report missing data
    if (!brand.logos?.length) {
      fetch("https://context.dev/api/report-missing-data", {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({
          domain: brand.domain,
          missing_field: "logos",
        }),
      });
    }
    ```
  </Accordion>
</AccordionGroup>

***

## SDK-Specific Issues

### TypeScript Type Errors

**Issue:** Type errors with SDK responses

**Solution:**

```typescript theme={null}
import ContextDev from "context.dev";

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

// Type the response
const response: ContextDev.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 'context_dev'`

**Solution:**

```bash theme={null}
# Reinstall the package
pip uninstall context.dev
pip install context.dev

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

# Verify installation
pip list | grep context
```

### Ruby Gem Installation Issues

**Issue:** Gem won't install or load

**Solution:**

```bash theme={null}
# Update bundler
gem update bundler

# Clear gem cache
gem cleanup

# Reinstall
gem uninstall context.dev
gem install context.dev

# Or with bundle
bundle update context.dev
```

***

## Debugging Tips

### Enable Debug Logging

<CodeGroup>
  ```typescript TypeScript theme={null}
  // Enable debug mode (if supported by SDK)
  const client = new ContextDev({
    apiKey: process.env.CONTEXT_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));
  ```

  ```python Python theme={null}
  import logging

  # Enable debug logging
  logging.basicConfig(level=logging.DEBUG)

  client = context_dev.ContextDev(
      api_key=os.environ.get("CONTEXT_DEV_API_KEY"),
  )
  ```

  ```ruby Ruby theme={null}
  # Enable verbose output
  client = ContextDev::Client.new(
    api_key: ENV['CONTEXT_DEV_API_KEY'],
    # debug: true
  )
  ```
</CodeGroup>

### Test with cURL

Isolate issues by testing with raw HTTP requests:

```bash theme={null}
curl https://api.context.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:

<CardGroup cols={2}>
  <Card title="Contact Support" icon="envelope" href="mailto:hello@context.dev">
    Email us at [hello@context.dev](mailto:hello@context.dev)
  </Card>

  <Card title="API Reference" icon="code" href="/api-reference">
    Review API documentation
  </Card>

  <Card title="Core Concepts" icon="book" href="/guides/get-started/core-concepts">
    Understand the fundamentals
  </Card>
</CardGroup>

***

<Note>
  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
</Note>
