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

# Developer Experience

> Comprehensive guide to LeadMagic API's developer-friendly features

LeadMagic is built with developers in mind. Every response includes rich metadata, standardized headers, and detailed error messages to make debugging and monitoring effortless.

## Why We Build This Way

<Info>
  **Our Philosophy:** APIs should be predictable, transparent, and never surprise you. Every decision in our API design prioritizes developer happiness and operational confidence.
</Info>

### Design Principles

<CardGroup cols={2}>
  <Card title="Standards-First" icon="certificate">
    We follow **RFC 9457** for errors, **IETF draft-ietf-httpapi-ratelimit-headers** for rate limits, and **RFC 7807** patterns throughout. No proprietary formats to learn.
  </Card>

  <Card title="Observable by Default" icon="eye">
    Every response includes 15+ headers giving you complete visibility into credits, rate limits, concurrency, and usage - without extra API calls.
  </Card>

  <Card title="Graceful Degradation" icon="shield-halved">
    Soft-mode rate limiting, automatic retries, and fallback mechanisms mean our limits guide you rather than break you.
  </Card>

  <Card title="Context-Rich Errors" icon="message-exclamation">
    Errors include actionable suggestions, documentation links, and machine-readable context so you can handle them programmatically.
  </Card>
</CardGroup>

### Why Response Headers Matter

Traditional APIs force you to make extra calls to check your balance or limits. LeadMagic embeds everything in response headers:

```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
# One request = Full operational context
curl -I 'https://api.leadmagic.io/v1/people/email-validation' \
  -H 'X-API-Key: YOUR_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{"email": "test@example.com"}'
```

**Every response includes:**

* Your remaining credits (`X-Credits-Remaining`)
* Rate limit status (`RateLimit-Remaining`, `RateLimit-Reset`)
* Daily quota (`X-RateLimit-Remaining-Daily`)
* Usage percentages (`X-RateLimit-Daily-Usage-Percent`)
* Soft mode status (`X-RateLimit-Soft-Mode`)

This means you can build dashboards, set up alerts, and implement smart rate limiting without polling separate endpoints.

***

## Response Headers

Every API response includes comprehensive headers for monitoring, debugging, and rate limit management.

<Tabs>
  <Tab title="Rate Limits" icon="gauge">
    ### IETF Standard Headers (Recommended)

    Following the [IETF draft-ietf-httpapi-ratelimit-headers](https://datatracker.ietf.org/doc/draft-ietf-httpapi-ratelimit-headers/) standard:

    | Header                | Description           | Example |
    | --------------------- | --------------------- | ------- |
    | `RateLimit-Limit`     | Max requests/min      | `300`   |
    | `RateLimit-Remaining` | Remaining this minute | `2847`  |
    | `RateLimit-Reset`     | Seconds until reset   | `42`    |

    ### Legacy X- Headers (Backwards Compatible)

    | Header                  | Description           | Example      |
    | ----------------------- | --------------------- | ------------ |
    | `X-RateLimit-Limit`     | Max requests/min      | `300`        |
    | `X-RateLimit-Remaining` | Remaining this minute | `2847`       |
    | `X-RateLimit-Reset`     | Unix timestamp reset  | `1706745600` |

    ### Daily Limit Headers

    | Header                        | Description          | Example      |
    | ----------------------------- | -------------------- | ------------ |
    | `X-RateLimit-Limit-Daily`     | Max requests/day     | `500000`     |
    | `X-RateLimit-Remaining-Daily` | Remaining today      | `485000`     |
    | `X-RateLimit-Reset-Daily`     | Unix timestamp reset | `1706832000` |
  </Tab>

  <Tab title="Credits & Usage" icon="coins">
    ### Credit Tracking

    | Header                | Description            | Example    |
    | --------------------- | ---------------------- | ---------- |
    | `X-Credits-Remaining` | Current credit balance | `15432.50` |
    | `X-Credits-Cost`      | Credits consumed       | `1`        |

    ### Usage Percentages

    | Header                            | Description            | Example |
    | --------------------------------- | ---------------------- | ------- |
    | `X-RateLimit-Daily-Usage-Percent` | Daily usage %          | `15`    |
    | `X-RateLimit-RPM-Usage-Percent`   | Current minute usage % | `5`     |

    <Tip>
      Use these headers to build dashboards, set up alerts at 50%/80%/95% thresholds, or implement automatic top-ups when credits run low.
    </Tip>
  </Tab>

  <Tab title="Soft Mode & Concurrency" icon="shield">
    ### Soft Mode

    LeadMagic uses "soft mode" rate limiting by default — we warn but don't block:

    | Header                      | Description                | Example |
    | --------------------------- | -------------------------- | ------- |
    | `X-RateLimit-Soft-Mode`     | Soft mode enabled          | `true`  |
    | `X-RateLimit-Soft-Exceeded` | Limit exceeded but allowed | `true`  |

    <Info>
      **Soft Mode** means we log rate limit violations but allow requests through. This prevents unexpected failures while giving you visibility into usage patterns.
    </Info>

    ### Concurrency

    | Header                  | Description                     | Example |
    | ----------------------- | ------------------------------- | ------- |
    | `X-Concurrent-Requests` | Current active requests         | `12`    |
    | `X-Active-Reservations` | Credit reservations in progress | `5`     |
    | `X-Peak-Concurrency`    | Peak concurrent this minute     | `45`    |
  </Tab>
</Tabs>

### Complete Header Reference

Here's a real-world example showing all headers in a typical response:

```http theme={"theme":{"light":"github-light","dark":"github-dark"}}
HTTP/2 200 OK
Content-Type: application/json

# IETF Standard Rate Limit Headers (Use these!)
RateLimit-Limit: 300
RateLimit-Remaining: 287
RateLimit-Reset: 42

# Legacy Rate Limit Headers (Backwards compatible)
X-RateLimit-Limit: 300
X-RateLimit-Remaining: 287
X-RateLimit-Reset: 1706745600

# Daily Limits
X-RateLimit-Limit-Daily: 500000
X-RateLimit-Remaining-Daily: 485000
X-RateLimit-Reset-Daily: 1706832000

# Credits Tracking
X-Credits-Remaining: 15432.50
X-Credits-Cost: 0.25

# Usage Metrics (percentages for easy alerting)
X-RateLimit-Daily-Usage-Percent: 3
X-RateLimit-RPM-Usage-Percent: 5

# Soft Mode (we warn but don't block)
X-RateLimit-Soft-Mode: true

# Concurrency
X-Concurrent-Requests: 12
X-Active-Reservations: 0
X-Peak-Concurrency: 45

# Request Tracking
X-Request-ID: req_abc123def456
```

<Tip>
  **Pro Tip:** Log these headers after every request. When debugging issues, you'll have complete visibility into your API state at that exact moment.
</Tip>

***

## Request Headers

### Required Headers

| Header         | Description                        | Example             |
| -------------- | ---------------------------------- | ------------------- |
| `X-API-Key`    | Your API key (case-insensitive)    | `lm_live_abc123...` |
| `Content-Type` | Always `application/json` for POST | `application/json`  |

<Info>
  **Case-Insensitive Authentication:** The `X-API-Key` header accepts any case variation: `X-API-Key`, `X-API-KEY`, `x-api-key` all work identically.
</Info>

### Optional Headers

| Header         | Description                 | Use Case                                                              |
| -------------- | --------------------------- | --------------------------------------------------------------------- |
| `User-Agent`   | Identifies your application | Used for timeout optimization (Clay integrations get longer timeouts) |
| `X-Request-ID` | Your request tracking ID    | Returned in error responses for debugging                             |
| `Accept`       | Response format             | `application/json` (default)                                          |

***

## Success Messages

Every endpoint returns a human-readable `message` field that tells you exactly what happened. These are designed to be user-friendly and can be displayed directly in your UI.

<Tabs>
  <Tab title="Email Validation" icon="envelope">
    | Message                               | Meaning                          |
    | ------------------------------------- | -------------------------------- |
    | `Email is valid.`                     | Email verified as deliverable    |
    | `Email is invalid.`                   | Email doesn't exist or bounces   |
    | `Unable to determine email validity.` | Verification inconclusive (free) |
  </Tab>

  <Tab title="Email Finder" icon="magnifying-glass">
    | Message                                           | Meaning                             |
    | ------------------------------------------------- | ----------------------------------- |
    | `Valid email found.`                              | Email found and verified (1 credit) |
    | `No email found for this person at this company.` | No email found (free)               |
  </Tab>

  <Tab title="Mobile Finder" icon="phone">
    | Message                                    | Meaning                             |
    | ------------------------------------------ | ----------------------------------- |
    | `Mobile number found.`                     | Phone number successfully retrieved |
    | `No mobile number found for this contact.` | No phone data available             |
  </Tab>

  <Tab title="Profile Search" icon="user">
    | Message                                | Meaning                             |
    | -------------------------------------- | ----------------------------------- |
    | `Profile found.`                       | Full profile data returned          |
    | `Profile not found or not accessible.` | Profile doesn't exist or is private |
  </Tab>

  <Tab title="Company Search" icon="building">
    | Message             | Meaning               |
    | ------------------- | --------------------- |
    | `Company found`     | Company data returned |
    | `Company not found` | No matching company   |
  </Tab>

  <Tab title="Role Finder" icon="briefcase">
    | Message                                   | Meaning                         |
    | ----------------------------------------- | ------------------------------- |
    | `Role Found`                              | Person with matching role found |
    | `No matching role found at this company.` | No matching role exists         |
  </Tab>

  <Tab title="People Search" icon="users">
    | Message           | Meaning                                      |
    | ----------------- | -------------------------------------------- |
    | `People found`    | People list returned                         |
    | `No people found` | No matching people for the requested filters |
  </Tab>

  <Tab title="Job Change Detector" icon="right-left">
    | Message                                                       | Meaning                    |
    | ------------------------------------------------------------- | -------------------------- |
    | `No job change detected. Still employed at expected company.` | Person still at company    |
    | `Job change detected. Person has moved to a new company.`     | Person changed jobs        |
    | `Never worked at the expected company.`                       | No employment record found |
  </Tab>
</Tabs>

<Note>
  **Why Messages Matter:** These aren't just for humans - they're also machine-readable. Check the `message` field to determine success vs. not-found scenarios, especially when `credits_consumed` might still be > 0 for verified "not found" results.
</Note>

## Analytics Endpoints

Monitor your API usage programmatically with our comprehensive analytics suite.

<Note>
  **All analytics endpoints are FREE** - they don't consume any credits and are exempt from rate limiting.
</Note>

### Dashboard Overview

Get a real-time snapshot of your account status:

<CodeGroup>
  ```bash cURL theme={"theme":{"light":"github-light","dark":"github-dark"}}
  curl 'https://api.leadmagic.io/v1/analytics/dashboard' \
    -H 'X-API-Key: YOUR_API_KEY'
  ```

  ```javascript Node.js theme={"theme":{"light":"github-light","dark":"github-dark"}}
  const response = await fetch('https://api.leadmagic.io/v1/analytics/dashboard', {
    headers: { 'X-API-Key': 'YOUR_API_KEY' }
  });
  const dashboard = await response.json();
  console.log(`Credits: ${dashboard.credits.current}`);
  console.log(`RPM Used: ${dashboard.rate_limit.minute.used}/${dashboard.rate_limit.minute.limit}`);
  ```

  ```python Python theme={"theme":{"light":"github-light","dark":"github-dark"}}
  import requests

  response = requests.get(
      'https://api.leadmagic.io/v1/analytics/dashboard',
      headers={'X-API-Key': 'YOUR_API_KEY'}
  )
  dashboard = response.json()
  print(f"Credits: {dashboard['credits']['current']}")
  print(f"Daily Used: {dashboard['rate_limit']['daily']['used']}")
  ```
</CodeGroup>

**Response:**

```json theme={"theme":{"light":"github-light","dark":"github-dark"}}
{
  "user": {
    "id": "user_abc123",
    "email": "developer@company.com"
  },
  "credits": {
    "current": 15432.50,
    "formatted": "$154.33"
  },
  "rate_limit": {
    "minute": {
      "limit": 300,
      "used": 45,
      "remaining": 255,
      "utilization": 15.0
    },
    "daily": {
      "limit": 500000,
      "used": 12500,
      "remaining": 487500,
      "utilization": 2.5
    }
  },
  "concurrency": {
    "current": 0,
    "peak": 23,
    "active_reservations": 0
  },
  "stats": {
    "today": {
      "requests": 1250,
      "credits": 875.50,
      "chargeable_requests": 1100,
      "chargeable_rate": 88.0,
      "unique_products": 5
    },
    "this_week": {
      "requests": 8500,
      "credits": 5200.25,
      "chargeable_requests": 7200,
      "chargeable_rate": 84.7,
      "unique_products": 8
    },
    "this_month": {
      "requests": 45000,
      "credits": 28500.00,
      "chargeable_requests": 38000,
      "chargeable_rate": 84.4,
      "unique_products": 12
    }
  }
}
```

### Available Analytics Endpoints

<CardGroup cols={2}>
  <Card title="GET /v1/analytics/dashboard" icon="gauge">
    Real-time dashboard with credits, rate limits, and usage stats for today, this week, and this month.
  </Card>

  <Card title="GET /v1/analytics/usage" icon="chart-bar">
    Daily usage summary with total requests, credits consumed, and chargeable rates.

    **Query params:** `?days=30` (1-90)
  </Card>

  <Card title="GET /v1/analytics/products" icon="boxes-stacked">
    Per-product breakdown showing requests, credits, success rates, and average costs.

    **Query params:** `?days=30` (1-90)
  </Card>

  <Card title="GET /v1/analytics/credits" icon="coins">
    Credit consumption history with daily breakdown and chargeable request analysis.

    **Query params:** `?days=30` (1-90)
  </Card>

  <Card title="GET /v1/analytics/summary" icon="calculator">
    All-time statistics including total requests, credits consumed, success rates, and first/last request timestamps.

    **Query params:** `?start_date=YYYY-MM-DD&end_date=YYYY-MM-DD`
  </Card>

  <Card title="GET /v1/analytics/daily" icon="calendar-days">
    Detailed daily metrics with latency percentiles, error rates, and performance data.

    **Query params:** `?days=30` (1-90)
  </Card>

  <Card title="GET /v1/analytics/day/:date" icon="calendar-day">
    Per-product breakdown for a specific day. Top 15 products plus aggregated "other" category.

    **Path param:** `:date` in YYYY-MM-DD format
  </Card>
</CardGroup>

### Usage Example: Daily Breakdown

```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
curl 'https://api.leadmagic.io/v1/analytics/usage?days=7' \
  -H 'X-API-Key: YOUR_API_KEY'
```

**Response:**

```json theme={"theme":{"light":"github-light","dark":"github-dark"}}
{
  "period": {
    "start": "2026-10-25",
    "end": "2026-11-01",
    "days": 7
  },
  "summary": {
    "total_requests": 8500,
    "chargeable_requests": 7200,
    "total_credits": 5200.25,
    "avg_credits_per_request": 0.61,
    "chargeable_rate": 84.7,
    "unique_products": 8
  },
  "daily": [
    {
      "date": "2026-11-01",
      "total_requests": 1250,
      "chargeable_requests": 1100,
      "total_credits": 875.50,
      "unique_products_used": 5
    }
    // ... more days
  ]
}
```

## Credits Endpoints

### Check Your Balance

<CodeGroup>
  ```bash cURL theme={"theme":{"light":"github-light","dark":"github-dark"}}
  curl 'https://api.leadmagic.io/v1/credits' \
    -H 'X-API-Key: YOUR_API_KEY'
  ```

  ```javascript Node.js theme={"theme":{"light":"github-light","dark":"github-dark"}}
  const response = await fetch('https://api.leadmagic.io/v1/credits', {
    headers: { 'X-API-Key': 'YOUR_API_KEY' }
  });
  const { credits } = await response.json();
  console.log(`Available credits: ${credits}`);
  ```

  ```python Python theme={"theme":{"light":"github-light","dark":"github-dark"}}
  import requests

  response = requests.get(
      'https://api.leadmagic.io/v1/credits',
      headers={'X-API-Key': 'YOUR_API_KEY'}
  )
  print(f"Credits: {response.json()['credits']}")
  ```
</CodeGroup>

**Response:**

```json theme={"theme":{"light":"github-light","dark":"github-dark"}}
{
  "credits": 15432.50
}
```

### Additional Credits Endpoints

| Endpoint                   | Method | Description                                      |
| -------------------------- | ------ | ------------------------------------------------ |
| `GET /v1/credits`          | GET    | Get current credit balance                       |
| `POST /v1/credits/refresh` | POST   | Force refresh credits from database              |
| `GET /v1/credits/health`   | GET    | Validate API key and check authentication status |

## Error Handling

LeadMagic follows [RFC 9457 Problem Details](https://www.rfc-editor.org/rfc/rfc9457) for standardized, machine-readable error responses.

### Error Response Format

```json {3,4,5,6,7,8} theme={"theme":{"light":"github-light","dark":"github-dark"}}
{
  "success": false,
  "errors": [
    {
      "type": "https://api.leadmagic.io/errors/insufficient_credits",
      "title": "Insufficient credits: need 5, have 2.50. Add credits to continue.",
      "status": 402,
      "detail": "This request requires 5 credit(s) but your account only has 2.50 credits remaining.",
      "instance": "/v1/people/mobile-finder#req_abc123",
      "code": "insufficient_credits",
      "action": "Add credits to your account at https://app.leadmagic.io/billing",
      "docs": "https://leadmagic.io/docs/v1/credits",
      "context": {
        "credits_required": 5,
        "credits_available": 2.50,
        "credits_needed": 2.50
      }
    }
  ],
  "meta": {
    "request_id": "req_abc123",
    "timestamp": "2026-10-01T12:00:00.000Z",
    "environment": "production"
  }
}
```

### Response Fields Explained

| Field     | Description                                       |
| --------- | ------------------------------------------------- |
| `type`    | URI identifying the error type (machine-readable) |
| `title`   | Human-readable summary (safe to display to users) |
| `status`  | HTTP status code                                  |
| `detail`  | Specific explanation of what went wrong           |
| `code`    | Short error code for programmatic handling        |
| `action`  | Suggested fix or next steps                       |
| `docs`    | Link to relevant documentation                    |
| `context` | Machine-readable details (varies by error type)   |

### HTTP Status Codes

<CardGroup cols={3}>
  <Card title="200" icon="circle-check" color="#22c55e">
    **Success** - Request completed
  </Card>

  <Card title="400" icon="circle-xmark" color="#f59e0b">
    **Bad Request** - Invalid input
  </Card>

  <Card title="401" icon="lock" color="#ef4444">
    **Unauthorized** - Invalid API key
  </Card>

  <Card title="402" icon="credit-card" color="#f59e0b">
    **Payment Required** - Low credits
  </Card>

  <Card title="429" icon="gauge-high" color="#f59e0b">
    **Too Many Requests** - Rate limited
  </Card>

  <Card title="500" icon="server" color="#ef4444">
    **Server Error** - Our fault
  </Card>
</CardGroup>

### Error Types

<Tabs>
  <Tab title="401 Authentication" icon="key">
    **HTTP 401 - Unauthorized**

    | Code                       | Description                               |
    | -------------------------- | ----------------------------------------- |
    | `missing_authentication`   | No API key provided in `X-API-Key` header |
    | `invalid_api_key`          | API key doesn't exist or is incorrect     |
    | `insufficient_permissions` | API key lacks access to this resource     |

    ```json {4,5} theme={"theme":{"light":"github-light","dark":"github-dark"}}
    {
      "errors": [{
        "type": "https://api.leadmagic.io/errors/invalid_api_key",
        "title": "Invalid API key. The key does not exist or is incorrect.",
        "status": 401,
        "code": "invalid_api_key",
        "docs": "https://leadmagic.io/docs/v1/authentication"
      }]
    }
    ```
  </Tab>

  <Tab title="400 Validation" icon="circle-exclamation">
    **HTTP 400 - Bad Request**

    | Code                     | Description                    |
    | ------------------------ | ------------------------------ |
    | `validation_error`       | Request validation failed      |
    | `missing_required_field` | Required field not provided    |
    | `invalid_json`           | Request body is not valid JSON |
    | `invalid_parameter`      | Parameter value is invalid     |

    ```json {4,5,7} theme={"theme":{"light":"github-light","dark":"github-dark"}}
    {
      "errors": [{
        "type": "https://api.leadmagic.io/errors/validation_error",
        "title": "Request validation failed. Check your input parameters.",
        "status": 400,
        "code": "validation_error",
        "param": ["email"],
        "docs": "https://leadmagic.io/docs/v1/making-api-calls"
      }]
    }
    ```
  </Tab>

  <Tab title="429 Rate Limits" icon="gauge">
    **HTTP 429 - Too Many Requests**

    | Code                  | Description                        |
    | --------------------- | ---------------------------------- |
    | `rate_limit_exceeded` | Exceeded per-minute or daily limit |

    <Note>
      Includes `Retry-After` header with seconds until reset.
    </Note>

    ```json {4,5,8,9} theme={"theme":{"light":"github-light","dark":"github-dark"}}
    {
      "errors": [{
        "type": "https://api.leadmagic.io/errors/rate_limit_exceeded",
        "title": "Rate limit exceeded: 300 requests per 1 minute.",
        "status": 429,
        "code": "rate_limit_exceeded",
        "detail": "You have exceeded the maximum allowed request rate.",
        "action": "Wait 42 seconds before retrying.",
        "context": {
          "limit": 300,
          "window": "1 minute",
          "remaining": 0,
          "reset_at": 1706745642,
          "retry_after_seconds": 42
        }
      }]
    }
    ```
  </Tab>

  <Tab title="402 Credits" icon="credit-card">
    **HTTP 402 - Payment Required**

    | Code                   | Description                         |
    | ---------------------- | ----------------------------------- |
    | `insufficient_credits` | Not enough credits for this request |

    ```json {4,5,8-11} theme={"theme":{"light":"github-light","dark":"github-dark"}}
    {
      "errors": [{
        "type": "https://api.leadmagic.io/errors/insufficient_credits",
        "title": "Insufficient credits: need 5, have 2.50.",
        "status": 402,
        "code": "insufficient_credits",
        "context": {
          "credits_required": 5,
          "credits_available": 2.50,
          "credits_needed": 2.50
        }
      }]
    }
    ```
  </Tab>

  <Tab title="5xx Server" icon="server">
    **HTTP 5xx - Server Errors**

    | Code                     | Status | Description              |
    | ------------------------ | ------ | ------------------------ |
    | `internal_error`         | 500    | Unexpected server error  |
    | `external_service_error` | 502    | Upstream service failed  |
    | `service_unavailable`    | 503    | Service temporarily down |

    ```json {4,5,7} theme={"theme":{"light":"github-light","dark":"github-dark"}}
    {
      "errors": [{
        "type": "https://api.leadmagic.io/errors/internal_error",
        "title": "Something went wrong on our end.",
        "status": 500,
        "code": "INTERNAL_ERROR",
        "action": "Wait 30 seconds and retry. Contact support@leadmagic.io if persistent."
      }]
    }
    ```
  </Tab>
</Tabs>

## Idempotency

Every request can include a unique identifier for tracking and debugging:

```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
curl -X POST 'https://api.leadmagic.io/v1/people/email-validation' \
  -H 'X-API-Key: YOUR_API_KEY' \
  -H 'X-Request-ID: my-unique-request-id-123' \
  -H 'Content-Type: application/json' \
  -d '{"email": "test@example.com"}'
```

The `X-Request-ID` is returned in error responses and logged for debugging:

```json theme={"theme":{"light":"github-light","dark":"github-dark"}}
{
  "errors": [{
    "instance": "/v1/people/email-validation#my-unique-request-id-123"
  }],
  "meta": {
    "request_id": "my-unique-request-id-123"
  }
}
```

## Graceful Degradation

LeadMagic is designed to handle failures gracefully:

| Scenario                     | Behavior                            |
| ---------------------------- | ----------------------------------- |
| **DO Timeout**               | Falls back to direct database query |
| **Rate limit in soft mode**  | Logs warning but allows request     |
| **External service failure** | Returns 502 with retry guidance     |
| **Database unavailable**     | Returns 503 with retry timing       |

<Info>
  **High Availability:** Our Durable Objects provide sub-millisecond rate limiting with automatic failover to PostgreSQL when needed.
</Info>

## Best Practices

<AccordionGroup>
  <Accordion title="Implement Exponential Backoff" icon="clock">
    When you receive a 429 error, use the `Retry-After` header:

    ```javascript theme={"theme":{"light":"github-light","dark":"github-dark"}}
    async function callWithRetry(fn, maxRetries = 3) {
      for (let i = 0; i < maxRetries; i++) {
        const response = await fn();

        if (response.status === 429) {
          const retryAfter = response.headers.get('Retry-After') || Math.pow(2, i);
          await sleep(retryAfter * 1000);
          continue;
        }

        return response;
      }
      throw new Error('Max retries exceeded');
    }
    ```
  </Accordion>

  <Accordion title="Monitor Rate Limit Headers" icon="gauge">
    Build proactive monitoring using response headers:

    ```javascript theme={"theme":{"light":"github-light","dark":"github-dark"}}
    async function monitoredRequest(url, options) {
      const response = await fetch(url, options);

      const dailyUsage = response.headers.get('X-RateLimit-Daily-Usage-Percent');
      const creditsRemaining = response.headers.get('X-Credits-Remaining');

      if (parseInt(dailyUsage) > 80) {
        alert('Approaching daily rate limit: ' + dailyUsage + '%');
      }

      if (parseFloat(creditsRemaining) < 1000) {
        alert('Low credits: ' + creditsRemaining);
      }

      return response;
    }
    ```
  </Accordion>

  <Accordion title="Use Request IDs for Debugging" icon="bug">
    Always include a request ID for easier debugging:

    ```javascript theme={"theme":{"light":"github-light","dark":"github-dark"}}
    const requestId = `req_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;

    const response = await fetch(url, {
      headers: {
        'X-API-Key': apiKey,
        'X-Request-ID': requestId,
        'Content-Type': 'application/json'
      },
      body: JSON.stringify(data)
    });

    // Log for debugging
    console.log(`Request ${requestId}: ${response.status}`);
    ```
  </Accordion>

  <Accordion title="Cache Credits Check" icon="database">
    Don't call `/v1/credits` before every request. Cache and refresh periodically:

    ```javascript theme={"theme":{"light":"github-light","dark":"github-dark"}}
    let cachedCredits = null;
    let lastFetch = 0;
    const CACHE_TTL = 60000; // 1 minute

    async function getCredits() {
      if (cachedCredits && Date.now() - lastFetch < CACHE_TTL) {
        return cachedCredits;
      }

      const response = await fetch('https://api.leadmagic.io/v1/credits', {
        headers: { 'X-API-Key': apiKey }
      });

      const { credits } = await response.json();
      cachedCredits = credits;
      lastFetch = Date.now();
      return credits;
    }
    ```
  </Accordion>
</AccordionGroup>

## SDK Support

While we don't have official SDKs yet, our REST API works seamlessly with any HTTP client:

<CardGroup cols={3}>
  <Card title="Node.js" icon="node-js">
    Use native `fetch` or `axios` for HTTP requests.
  </Card>

  <Card title="Python" icon="python">
    Use `requests` or `httpx` for async support.
  </Card>

  <Card title="Any Language" icon="code">
    Any HTTP client works - just send JSON with your API key.
  </Card>
</CardGroup>

***

## Why We Built It This Way

<AccordionGroup>
  <Accordion title="RFC 9457 Problem Details for Errors" icon="standard">
    Traditional APIs return cryptic errors like `{"error": "Bad request"}`. This leaves developers guessing what went wrong and how to fix it.

    **Our approach:** Every error follows [RFC 9457 Problem Details](https://www.rfc-editor.org/rfc/rfc9457), a standard designed by the IETF specifically for HTTP API errors. This means:

    * **`type`**: A URI identifying the error type (bookmarkable, consistent)
    * **`title`**: Human-readable summary you can show users
    * **`status`**: HTTP status code (redundant but useful)
    * **`detail`**: Specific explanation of what went wrong
    * **`action`**: Suggested fix (unique to LeadMagic)
    * **`docs`**: Link to relevant documentation
    * **`context`**: Machine-readable details (credits needed, rate limits, etc.)

    This isn't just for show - your code can programmatically handle errors based on `type` while showing users the `title` and `action`.
  </Accordion>

  <Accordion title="IETF Rate Limit Headers" icon="gauge">
    We implement the [IETF draft-ietf-httpapi-ratelimit-headers](https://datatracker.ietf.org/doc/draft-ietf-httpapi-ratelimit-headers/) standard for rate limit headers:

    ```http theme={"theme":{"light":"github-light","dark":"github-dark"}}
    RateLimit-Limit: 300
    RateLimit-Remaining: 287
    RateLimit-Reset: 42
    ```

    **Why this matters:**

    * These headers are on track to become an official standard
    * Libraries already support them (many HTTP clients auto-parse)
    * Consistent across all modern APIs that implement the spec
    * No need to learn LeadMagic-specific header names

    We also include legacy `X-RateLimit-*` headers for backwards compatibility.
  </Accordion>

  <Accordion title="Soft Mode Rate Limiting" icon="shield-heart">
    Most APIs hard-block you when you hit limits. This causes:

    * Unexpected failures in production
    * Data loss if you're mid-batch
    * Frustrated developers

    **Our approach:** Soft mode warns but doesn't block. When you exceed limits, we:

    1. Log the violation
    2. Set `X-RateLimit-Soft-Exceeded: true`
    3. **Still process your request**

    This gives you time to fix your implementation without breaking production. Watch for the header in logs and fix before we have to enforce limits.
  </Accordion>

  <Accordion title="Credits in Every Response" icon="coins">
    Checking your balance shouldn't require extra API calls. Every enrichment response includes:

    ```http theme={"theme":{"light":"github-light","dark":"github-dark"}}
    X-Credits-Remaining: 15432.50
    X-Credits-Cost: 1
    ```

    **Benefits:**

    * Build credit alerts without polling
    * Log spend per-request for cost attribution
    * Pause automatically when credits run low
    * Never wonder "how much did that cost?"
  </Accordion>

  <Accordion title="Meaningful Success Messages" icon="message-check">
    Our `message` field isn't just "success" - it tells you what actually happened:

    * `"Email is valid."` - Great, use it!
    * `"Email is invalid."` - Do not email
    * `"Unable to determine email validity."` - Unknown result (free)

    This lets you:

    * Display messages directly to end users
    * Make programmatic decisions based on outcomes
    * Distinguish between "not found" and "error"
  </Accordion>

  <Accordion title="Zero-Cost Analytics" icon="chart-pie">
    All analytics endpoints are **FREE** - no credits consumed, no rate limits. This means you can:

    * Poll `/v1/analytics/dashboard` every minute
    * Build real-time dashboards
    * Set up alerting without worrying about cost
    * Audit your usage as often as needed

    We want you to have complete visibility into your API usage.
  </Accordion>
</AccordionGroup>

## Next Steps

<CardGroup cols={2}>
  <Card title="Authentication" icon="key" href="/docs/v1/authentication">
    Deep dive into API key management and security best practices.
  </Card>

  <Card title="Credits Guide" icon="coins" href="/docs/v1/credits">
    Understand credit costs, billing, and optimization strategies.
  </Card>

  <Card title="API Reference" icon="book" href="/docs/v1/reference/email-validation">
    Explore all available endpoints in the interactive playground.
  </Card>

  <Card title="Integrations" icon="plug" href="/docs/v1/integrations">
    Connect LeadMagic with Clay, Make, Zapier, and more.
  </Card>
</CardGroup>
