API Responses

Understanding response codes, formats, and error handling strategies

Success Responses

302 Found (Redirect)

Standard successful response

The API returns a 302 redirect to the actual image URL. This is the normal, successful response you'll receive.

Response:

HTTP/1.1 302 Found
Location: https://images.unsplash.com/photo-123...
X-Cache: HIT
X-Image-Source: unsplash
X-RateLimit-Limit: 1000
X-RateLimit-Remaining: 987
X-Response-Time: 45ms

How to use:

HTML:

<img src="/api/image?query=..." />

Automatically follows redirect

JavaScript:

response.headers.get('Location')

Get image URL directly

Client Errors (4xx)

400 Bad Request

Invalid parameters or missing required fields

{
  "error": "Missing required parameter: query",
  "code": "MISSING_PARAMETER",
  "parameter": "query"
}

Common causes:

  • Missing query parameter
  • Invalid width or height (must be 100-4000)
  • Malformed parameters

Fix: Verify all parameters are correctly formatted and within valid ranges

401 Unauthorized

Invalid or expired API key

{
  "error": "Invalid API key",
  "code": "INVALID_API_KEY"
}

Common causes:

  • API key doesn't exist
  • API key has been revoked
  • Incorrect API key format

Fix: Verify your API key is correct and hasn't been revoked. Get a new key if needed.

429 Too Many Requests

Rate limit exceeded

{
  "error": "Rate limit exceeded",
  "code": "RATE_LIMIT_EXCEEDED",
  "limit": 1000,
  "remaining": 0,
  "reset": "2025-02-09T12:00:00Z",
  "retryAfter": 3600
}

Response headers:

X-RateLimit-Limit: 1000
X-RateLimit-Remaining: 0
X-RateLimit-Reset: 2025-02-09T12:00:00Z
Retry-After: 3600

Fix: Wait for the time specified in Retry-After header, or upgrade your plan.

Server Errors (5xx)

500 Internal Server Error

Unexpected server error

{
  "error": "Internal server error",
  "code": "INTERNAL_ERROR"
}

Fix: This is our fault. Retry after a few moments. If it persists, contact support with the request details.

503 Service Unavailable

Service temporarily unavailable

{
  "error": "Service temporarily unavailable",
  "code": "SERVICE_UNAVAILABLE"
}

Fix: Retry with exponential backoff. Check our status page for updates.

Error Handling Best Practices

Implement Retry Logic

async function fetchImage(query, options = {}) {
  const maxRetries = 3;
  
  for (let attempt = 0; attempt < maxRetries; attempt++) {
    try {
      const response = await fetch(`/api/image?query=${query}`, options);
      
      // Success
      if (response.status === 302) {
        return response.headers.get('Location');
      }
      
      // Rate limit - respect Retry-After
      if (response.status === 429) {
        const retryAfter = response.headers.get('Retry-After');
        const delay = retryAfter ? parseInt(retryAfter) * 1000 : Math.pow(2, attempt) * 1000;
        await new Promise(resolve => setTimeout(resolve, delay));
        continue;
      }
      
      // Client error - don't retry
      if (response.status >= 400 && response.status < 500) {
        const error = await response.json();
        throw new Error(error.error);
      }
      
      // Server error - retry with backoff
      if (response.status >= 500) {
        await new Promise(resolve => setTimeout(resolve, Math.pow(2, attempt) * 1000));
        continue;
      }
    } catch (error) {
      if (attempt === maxRetries - 1) throw error;
    }
  }
  
  throw new Error('Max retries exceeded');
}

Handle Errors Gracefully

try {
  const imageUrl = await fetchImage('mountains');
  setImageSrc(imageUrl);
} catch (error) {
  // Show fallback image
  setImageSrc('/fallback-image.jpg');
  
  // Log error for monitoring
  console.error('Image fetch failed:', error);
  
  // Show user-friendly message
  showToast('Could not load image. Please try again.');
}

Monitor Error Rates

Track error responses to identify issues early:

  • High 4xx rates → Check your implementation
  • High 429 rates → Consider upgrading plan
  • High 5xx rates → Contact support

Error Code Reference

CodeHTTP StatusDescriptionRetry?
MISSING_PARAMETER400Required parameter missing❌ No
INVALID_PARAMETER400Parameter value invalid❌ No
INVALID_API_KEY401API key invalid or revoked❌ No
RATE_LIMIT_EXCEEDED429Too many requests✅ Yes (after delay)
INTERNAL_ERROR500Server error✅ Yes (with backoff)
SERVICE_UNAVAILABLE503Service down or overloaded✅ Yes (with backoff)