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

# SDKs & Code Examples

> Multi-language examples for common API operations

# SDKs & Code Examples

Naturalead provides a REST API accessible from any language. Below are examples and helper patterns for the most common languages.

<Info>
  Official SDKs are on the roadmap. For now, use the REST API directly with any HTTP client.
</Info>

## Quick Reference

<CardGroup cols={3}>
  <Card title="cURL" icon="terminal" href="/sdks/curl">
    Command-line examples for every endpoint.
  </Card>

  <Card title="Python" icon="python" href="/sdks/python">
    Using `requests` or `httpx` with helper patterns.
  </Card>

  <Card title="JavaScript" icon="js" href="/sdks/javascript">
    Node.js examples with `fetch` and error handling.
  </Card>
</CardGroup>

## Authentication Setup

All examples assume you have an API key stored in an environment variable:

<CodeGroup>
  ```bash Shell theme={null}
  export NATURALEAD_API_KEY="nl_live_your_api_key_here"
  ```

  ```python Python theme={null}
  import os
  API_KEY = os.environ["NATURALEAD_API_KEY"]
  BASE_URL = "https://api.naturalead.ai/api"
  ```

  ```javascript Node.js theme={null}
  const API_KEY = process.env.NATURALEAD_API_KEY;
  const BASE_URL = "https://api.naturalead.ai/api";
  ```
</CodeGroup>

## Common Patterns

### Error Handling

Always check the HTTP status code before parsing the response body:

<CodeGroup>
  ```python Python theme={null}
  import requests

  def api_request(method, path, **kwargs):
      response = requests.request(
          method,
          f"{BASE_URL}{path}",
          headers={"X-API-Key": API_KEY, "Content-Type": "application/json"},
          **kwargs
      )

      if response.status_code == 429:
          retry_after = int(response.headers.get("Retry-After", 5))
          raise Exception(f"Rate limited. Retry after {retry_after}s")

      if not response.ok:
          error = response.json().get("error", "Unknown error")
          raise Exception(f"API error {response.status_code}: {error}")

      if response.status_code == 204:
          return None

      return response.json()
  ```

  ```javascript Node.js theme={null}
  async function apiRequest(method, path, body) {
    const response = await fetch(`${BASE_URL}${path}`, {
      method,
      headers: {
        "X-API-Key": API_KEY,
        "Content-Type": "application/json",
      },
      body: body ? JSON.stringify(body) : undefined,
    });

    if (response.status === 429) {
      const retryAfter = response.headers.get("Retry-After") || "5";
      throw new Error(`Rate limited. Retry after ${retryAfter}s`);
    }

    if (!response.ok) {
      const { error } = await response.json();
      throw new Error(`API error ${response.status}: ${error}`);
    }

    if (response.status === 204) return null;
    return response.json();
  }
  ```
</CodeGroup>

### Rate Limit Handling

Monitor rate limit headers to proactively throttle your requests:

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

def api_request_with_backoff(method, path, max_retries=3, **kwargs):
    for attempt in range(max_retries):
        response = requests.request(
            method,
            f"{BASE_URL}{path}",
            headers={"X-API-Key": API_KEY},
            **kwargs
        )

        remaining = int(response.headers.get("RateLimit-Remaining", 100))
        if remaining < 10:
            reset = int(response.headers.get("RateLimit-Reset", 5))
            time.sleep(min(reset, 5))

        if response.status_code != 429:
            return response

        retry_after = int(response.headers.get("Retry-After", 2 ** attempt))
        time.sleep(retry_after)

    raise Exception("Max retries exceeded")
```
