← Back to documentation

api-onboarding-guide

BuyWhere API Onboarding Guide

Get from first successful API call to production integration in under 10 minutes.

Prerequisites

  • A BuyWhere API key (get one free)
  • curl, a browser, or any HTTP client

1. Authentication

Making Your First Request

Test your API key immediately:

curl https://api.buywhere.ai/v1/search?q=headphones&limit=3 \
  -H "Authorization: Bearer bw_live_YOUR_KEY"

Expected response:

{
  "total": 1247,
  "items": [...]
}

If you see a 401 error, your key isn't working.

Why 401 Happens

Missing header:

# WRONG - no auth header
curl https://api.buywhere.ai/v1/search?q=laptop

# FIXED - include Bearer token
curl https://api.buywhere.ai/v1/search?q=laptop \
  -H "Authorization: Bearer bw_live_YOUR_KEY"

Wrong header format:

# WRONG - lowercase "bearer"
-H "bearer: bw_live_YOUR_KEY"

# WRONG - missing "Bearer" prefix
-H "Authorization: bw_live_YOUR_KEY"

# CORRECT
-H "Authorization: Bearer bw_live_YOUR_KEY"

Wrong key:

# WRONG - test key in production (or vice versa)
-H "Authorization: Bearer bw_test_YOUR_KEY"  # if using live endpoint

API Key Format Reference

PrefixEnvironmentUse Case
bw_live_ProductionReal product data, affiliate tracking
bw_test_SandboxDevelopment, testing, demos

Quick SDK Setup

Python:

from buywhere_sdk import BuyWhere

client = BuyWhere(api_key="bw_live_YOUR_KEY")
results = client.search("laptop", limit=5)
print(results.total, "products found")

JavaScript:

import { BuyWhereClient } from "@buywhere/sdk";

const client = new BuyWhereClient("bw_live_YOUR_KEY");
const results = await client.search({ q: "laptop", limit: 5 });
console.log(results.total, "products found");

2. Rate Limits

Limits by Tier

TierRequests/MinuteBurstDaily Cap
Free100201,000
Basic50010010,000
Pro1,000500100,000
Enterprise10,000+CustomUnlimited

Reading Rate Limit Headers

Every API response includes your current status:

X-RateLimit-Limit: 1000
X-RateLimit-Remaining: 847
X-RateLimit-Reset: 1713246000
  • Limit — your total per-minute allowance
  • Remaining — requests left in this window
  • Reset — Unix timestamp when the window resets

What 429 Looks Like

{
  "detail": "Rate limit exceeded. Retry after 43 seconds."
}

Headers include:

HTTP/1.1 429 Too Many Requests
Retry-After: 43

Retry Strategy

Don't do this:

# BAD: retry immediately, hammers the API
for attempt in range(10):
    response = requests.get(url, headers=headers)
    if response.status_code == 429:
        continue  # Immediate retry - causes thundering herd

Do this instead:

import time
import httpx

def fetch_with_backoff(url, headers, max_retries=5):
    for attempt in range(max_retries):
        response = httpx.get(url, headers=headers)
        
        if response.status_code != 429:
            return response
        
        retry_after = int(response.headers.get("Retry-After", 60))
        wait = retry_after * (2 ** attempt)  # Exponential backoff
        print(f"Rate limited. Waiting {wait}s...")
        time.sleep(wait)
    
    raise Exception("Max retries exceeded")

The Python SDK handles this automatically:

from buywhere_sdk import BuyWhere

client = BuyWhere(api_key="bw_live_KEY")
# SDK retries on 429 with exponential backoff - no extra code needed
results = client.search("laptop")

Staying Within Limits

Monitor your usage:

def make_request():
    response = httpx.get(url, headers=headers)
    
    remaining = int(response.headers.get("X-RateLimit-Remaining", 0))
    limit = int(response.headers.get("X-RateLimit-Limit", 1000))
    
    usage_pct = (limit - remaining) / limit
    if usage_pct > 0.8:
        print("WARNING: 80%+ rate limit used")
    
    return response

Cache aggressively:

import hashlib
import json
import time

cache = {}

def cached_search(query, max_age=300):  # 5-minute cache
    key = hashlib.md5(query.encode()).hexdigest()
    
    if key in cache:
        result, timestamp = cache[key]
        if time.time() - timestamp < max_age:
            return result  # Cache hit
    
    result = client.search(query)
    cache[key] = (result, time.time())
    return result

3. Error Reference

HTTP Status Codes

StatusMeaningCommon Causes
200SuccessNormal response
201CreatedAlert created, key provisioned
204No ContentDelete succeeded
400Bad RequestInvalid query parameters
401UnauthorizedMissing/invalid API key
403ForbiddenValid key but insufficient permissions
404Not FoundProduct/endpoint doesn't exist
409ConflictDuplicate resource (e.g., existing alert)
422UnprocessableValidation error in request body
429Rate LimitedToo many requests
500Server ErrorInternal error, not your fault
503UnavailableTemporary outage

Error Response Format

All errors follow a consistent structure:

{
  "detail": "Human-readable error message"
}

Some errors include additional context:

{
  "detail": [
    {
      "loc": ["body", "product_ids"],
      "msg": "ensure this value has at least 2 items",
      "type": "value_error.too_small"
    }
  ]
}

Common Errors and Fixes

401 — Invalid or revoked API key:

{"detail": "Invalid or revoked API key"}

Fix: Verify your key is correct. Keys are prefixed bw_live_ or bw_test_.

403 — Insufficient permissions:

{"detail": "API key lacks required permissions"}

Fix: Your key tier may not support this endpoint. Contact support to upgrade.

404 — Product not found:

{"detail": "Product not found"}

Fix: The product ID may be stale or the product was removed from the catalog.

422 — Validation error:

{
  "detail": [
    {"loc": ["query", "limit"], "msg": "ensure this value is less than or equal to 100"}
  ]
}

Fix: Check the loc field to see which parameter failed validation.

429 — Rate limit exceeded:

{"detail": "Rate limit exceeded. Retry after 43 seconds."}

Fix: Wait and retry. Use the Retry-After header value.

500 — Internal server error:

{"detail": "Internal server error"}

Fix: This is BuyWhere's issue, not yours. Retry after a few seconds. If persistent, check status.buywhere.ai.


4. Troubleshooting Checklist

Run through this before asking for help:

  • API key starts with bw_live_ or bw_test_ (not sk_live_ or other prefixes)
  • Header format is exactly Authorization: Bearer YOUR_KEY
  • No whitespace or newlines in the key
  • Using production key (bw_live_) for production API (api.buywhere.ai)
  • Request is under rate limit (check X-RateLimit-Remaining)
  • Product ID or query syntax is valid
  • Required parameters are present (e.g., q for search)

Quick Diagnostic Request

To verify your key and connectivity:

curl https://api.buywhere.ai/health \
  -H "Authorization: Bearer bw_live_YOUR_KEY"

Expected:

{"status": "ok", "version": "1.0.0", "environment": "production"}

If this fails but search works, there's an endpoint-specific issue.


5. Getting Help

When contacting support, include:

  1. Your API key prefix (not the full key)
  2. The request that failed (endpoint, parameters)
  3. The full error response
  4. Timestamp of the failure