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

# Status Codes

> Complete reference for HTTP status codes, rate limiting, and authentication

## Authentication

The Token Launch API is **currently open access** with no API keys required:

* ✅ No authentication needed
* ✅ No API keys to manage
* ✅ IP-based rate limiting only

<Note>
  **Need higher rate limits?** DM [@zcombinatorio](https://x.com/zcombinatorio) on Twitter to discuss increased limits for your use case.
</Note>

## Rate Limiting

All endpoints use IP-based rate limiting:

### Current Limits

<AccordionGroup>
  <Accordion title="Standard Rate Limit" icon="gauge">
    **8 requests per IP per 2-minute window**

    * Applies to all endpoints uniformly
    * Resets every 2 minutes
    * No exceptions for different endpoint types
    * Based on client IP address only

    ```bash theme={null}
    # Example rate limit headers (may be added in future)
    X-RateLimit-Limit: 4
    X-RateLimit-Remaining: 3
    X-RateLimit-Reset: 1642248520
    ```
  </Accordion>

  <Accordion title="Rate Limit Exceeded" icon="clock">
    **HTTP 429 - Too Many Requests**

    ```json theme={null}
    {
      "error": "Too many requests from this IP, please try again later."
    }
    ```

    **When this happens:**

    * Wait for the 2-minute window to reset
    * Implement exponential backoff
    * Consider caching responses when possible
  </Accordion>

  <Accordion title="Higher Limits Available" icon="arrow-up">
    **Need more requests?**

    For applications requiring higher rate limits:

    1. DM [@zcombinatorio](https://x.com/zcombinatorio) on Twitter
    2. Describe your use case and expected volume
    3. Custom rate limits can be arranged
    4. No cost for legitimate use cases

    **What to include in your DM:**

    * Project description
    * Expected requests per minute
    * Use case (web app, bot, integration, etc.)
    * Timeline for deployment
  </Accordion>
</AccordionGroup>

## HTTP Status Codes

### Success Codes

<AccordionGroup>
  <Accordion title="200 - OK" icon="check">
    **Successful Request**

    The request was processed successfully. Response contains the requested data.

    **Endpoints:** All endpoints return 200 on success
    **Response:** JSON object with requested data
  </Accordion>
</AccordionGroup>

### Client Error Codes (4xx)

<AccordionGroup>
  <Accordion title="400 - Bad Request" icon="ban">
    **Invalid Request**

    The request was malformed or contained invalid parameters.

    **Common causes:**

    * Missing required fields
    * Invalid parameter values
    * Business logic violations
    * Invalid Base58 addresses

    **Examples:**

    ```json theme={null}
    {
      "error": "Missing required fields: name, symbol, and payerPublicKey are required"
    }
    ```

    ```json theme={null}
    {
      "error": "CA ending must be 3 characters or less"
    }
    ```

    ```json theme={null}
    {
      "error": "Requested amount exceeds available claim amount"
    }
    ```
  </Accordion>

  <Accordion title="404 - Not Found" icon="magnifying-glass">
    **Resource Not Found**

    The requested resource doesn't exist.

    **Common causes:**

    * Token not found in database
    * Invalid transaction keys
    * Token not launched through this API

    **Examples:**

    ```json theme={null}
    {
      "error": "Token not found"
    }
    ```

    ```json theme={null}
    {
      "error": "Token keypair not found. Please call /launch first."
    }
    ```
  </Accordion>

  <Accordion title="429 - Too Many Requests" icon="gauge">
    **Rate Limited**

    Client has exceeded the IP-based rate limit.

    **Rate limit:** 8 requests per IP per 2-minute window

    **Response:**

    ```json theme={null}
    {
      "error": "Too many requests from this IP, please try again later."
    }
    ```

    **Solutions:**

    * Wait for rate limit window to reset (2 minutes)
    * Implement exponential backoff
    * Cache responses when possible
    * DM [@zcombinatorio](https://x.com/zcombinatorio) for higher limits
  </Accordion>
</AccordionGroup>

### Server Error Codes (5xx)

<AccordionGroup>
  <Accordion title="500 - Internal Server Error" icon="server">
    **Server Error**

    An unexpected error occurred on the server.

    **Common causes:**

    * Configuration issues
    * Blockchain network problems
    * External service failures
    * Database connectivity issues

    **Examples:**

    ```json theme={null}
    {
      "error": "RPC_URL not configured"
    }
    ```

    ```json theme={null}
    {
      "error": "Failed to create launch transaction"
    }
    ```

    ```json theme={null}
    {
      "error": "Helius API key not configured"
    }
    ```

    **Solutions:**

    * Retry the request (may be transient)
    * Check [`/health`](/api-reference/utility/health) endpoint
    * Report persistent issues to [@zcombinatorio](https://x.com/zcombinatorio)
  </Accordion>
</AccordionGroup>

## Rate Limit Best Practices

### Client-Side Implementation

<CodeGroup>
  ```javascript browser theme={null}
  class APIClient {
    constructor() {
      this.requestCount = 0;
      this.windowStart = Date.now();
      this.maxRequests = 8;
      this.windowMs = 2 * 60 * 1000; // 2 minutes
    }

    async makeRequest(url, options) {
      // Check if we're approaching rate limit
      const now = Date.now();
      const windowElapsed = now - this.windowStart;

      if (windowElapsed >= this.windowMs) {
        // Reset window
        this.requestCount = 0;
        this.windowStart = now;
      }

      if (this.requestCount >= this.maxRequests) {
        const waitTime = this.windowMs - windowElapsed;
        throw new Error(`Rate limited. Wait ${Math.ceil(waitTime / 1000)} seconds.`);
      }

      try {
        const response = await fetch(url, options);

        if (response.status === 429) {
          // Server-side rate limit hit
          throw new Error('Rate limited by server. Please wait 2 minutes.');
        }

        this.requestCount++;
        return response;
      } catch (error) {
        if (error.message.includes('rate limit')) {
          // Exponential backoff
          await this.exponentialBackoff();
          return this.makeRequest(url, options);
        }
        throw error;
      }
    }

    async exponentialBackoff(attempt = 0) {
      const delay = Math.min(1000 * (2 ** attempt), 30000);
      const jitter = Math.random() * 1000;
      await new Promise(resolve => setTimeout(resolve, delay + jitter));
    }
  }
  ```

  ```python server theme={null}
  import time
  import requests
  from datetime import datetime, timedelta

  class APIClient:
      def __init__(self):
          self.request_count = 0
          self.window_start = datetime.now()
          self.max_requests = 8
          self.window_duration = timedelta(minutes=2)

      def make_request(self, url, **kwargs):
          # Check rate limit window
          now = datetime.now()
          if now - self.window_start >= self.window_duration:
              self.request_count = 0
              self.window_start = now

          if self.request_count >= self.max_requests:
              wait_seconds = (self.window_duration - (now - self.window_start)).total_seconds()
              raise Exception(f"Rate limited. Wait {wait_seconds:.0f} seconds.")

          try:
              response = requests.request(**kwargs, url=url, timeout=30)

              if response.status_code == 429:
                  self.exponential_backoff()
                  return self.make_request(url, **kwargs)

              response.raise_for_status()
              self.request_count += 1
              return response.json()

          except requests.RequestException as e:
              if "429" in str(e):
                  self.exponential_backoff()
                  return self.make_request(url, **kwargs)
              raise

      def exponential_backoff(self, attempt=0):
          delay = min(2 ** attempt, 30)  # Cap at 30 seconds
          time.sleep(delay)
  ```
</CodeGroup>

### Caching Strategies

<AccordionGroup>
  <Accordion title="Eligible for Caching" icon="database">
    **Safe to cache:**

    * Token verification results (`/verify-token`)
    * Token launch confirmations (once completed)
    * Health check results (short-term)

    **Cache duration suggestions:**

    * Token existence: Permanent (tokens don't get deleted)
    * Health status: 30-60 seconds
    * Launch confirmations: Permanent
  </Accordion>

  <Accordion title="Not Safe to Cache" icon="ban">
    **Do not cache:**

    * Claim eligibility (`/claims/:tokenAddress`) - changes over time
    * Unsigned transactions (`/launch`, `/claims/mint`) - time-sensitive
    * Error responses - may be transient

    **Why not to cache:**

    * Claim eligibility changes every 24 hours
    * Transactions have expiration times
    * Cached errors prevent retry of transient issues
  </Accordion>
</AccordionGroup>

## Monitoring Rate Limits

### Client-Side Tracking

```javascript theme={null}
// Track your usage
const usage = {
  requests: 0,
  windowStart: Date.now(),

  log(endpoint) {
    this.requests++;
    console.log(`Request ${this.requests}/8 to ${endpoint}`);

    if (this.requests >= 4) {
      const nextWindow = new Date(this.windowStart + 2 * 60 * 1000);
      console.warn(`Rate limit reached. Next window: ${nextWindow.toLocaleTimeString()}`);
    }
  },

  reset() {
    this.requests = 0;
    this.windowStart = Date.now();
    console.log('Rate limit window reset');
  }
};

// Use in your API calls
usage.log('/launch');
```

### Server Response Patterns

Look for these patterns in responses:

```javascript theme={null}
// Rate limit approaching (implement client-side tracking)
if (clientRequestCount >= 3) {
  showWarning('Approaching rate limit. Next request may be delayed.');
}

// Rate limit hit
if (response.status === 429) {
  showError('Rate limited. Please wait 2 minutes before trying again.');
  // Set timer for retry
  setTimeout(() => {
    showInfo('Rate limit window reset. You can try again now.');
  }, 2 * 60 * 1000);
}
```

## Contact for Support

<Card title="Need Help?" icon="envelope">
  * **Rate limit increases**: DM [@zcombinatorio](https://x.com/zcombinatorio)
  * **Technical issues**: Report persistent 500 errors
  * **Integration questions**: Ask about best practices
  * **Feature requests**: Suggest improvements

  **Response time**: Usually within 24 hours
</Card>
