Skip to main content

Python Best Buy API Wrapper

image CI Main CI Dev

A modern, high-performance, asynchronous and synchronous Python SDK for the Best Buy REST API.


Features

  • Products API: Search by SKU, UPC, description, customer review criteria, or complex query expressions.
  • Recommendations API: Access Trending products, Most Viewed, Also Bought, Also Viewed, and Viewed Ultimately Bought.
  • Buying Options (Open Box) API: Access open-box availability, condition ratings, and special pricing by SKU, list of SKUs, or category.
  • Stores API: Store lookup by store ID, ZIP/postal code, city, region/state, or geographic radius search (area(lat,lng,distance)).
  • Categories API: Query categories by ID, name, or custom filters.
  • Bulk Data API: Download and parse daily archives and subsets (JSON/XML).
  • Dual Sync & Async Support: Unified API with high-performance HTTP connection pooling via httpx.
  • CursorMark Pagination: Stream large result sets seamlessly with iter_cursor() / aiter_cursor() and iter_pages() / aiter_pages().
  • Granular Error Handling: Specific exceptions for HTTP 401/403, 404, 429 rate limits, and server errors.
  • Type Safety: Fully typed with PEP 561 py.typed support.

Installation

Using uv (recommended):

uv add bestbuyapi

Or with pip:

pip install bestbuyapi

Configuration

You can supply your API key directly or define BESTBUY_API_KEY in your environment or a .env file:

BESTBUY_API_KEY=your_api_key_here

Quickstart

Synchronous Usage

from bestbuyapi import BestBuyAPI

# Automatically reads BESTBUY_API_KEY from environment if not provided
with BestBuyAPI() as bb:
    # 1. Search Products
    product = bb.products.search_by_sku(5985609, format="json")
    print(product)

    # 2. Recommendations
    trending = bb.recommendations.trending(category_id="abcat0400000")
    also_bought = bb.recommendations.also_bought(8880044)

    # 3. Open Box / Buying Options
    open_box_deals = bb.open_box.search_by_sku(8610161)

    # 4. Stores by Radius (Latitude, Longitude, Distance in Miles)
    nearby_stores = bb.stores.search_by_area(lat=44.88476, lng=-93.30058, distance_miles=10)

    # 5. Categories
    cat = bb.categories.search_by_id("abcat0101001")

    # 6. Bulk Archives
    all_categories = bb.bulk.archive("categories", "json")

Asynchronous Usage

import asyncio
from bestbuyapi import AsyncBestBuyAPI

async def main():
    async with AsyncBestBuyAPI() as bb:
        # Concurrent API calls
        product_task = bb.products.asearch_by_sku(5985609, format="json")
        trending_task = bb.recommendations.atrending()
        stores_task = bb.stores.asearch_by_postal_code(55423)

        product, trending, stores = await asyncio.gather(
            product_task, trending_task, stores_task
        )
        print(f"Product: {product['products'][0]['name']}")
        print(f"Trending count: {len(trending['results'])}")
        print(f"Stores found: {len(stores['stores'])}")

asyncio.run(main())

Deep Pagination & Cursor Streaming

For large query results, use cursor marks to walk the result set efficiently without deep paging overhead:

Sync Cursor Streaming

with BestBuyAPI() as bb:
    # Streams batches of up to 100 products using cursorMark bookmarks
    for page in bb.products.iter_cursor(query="type=HardGood", page_size=100):
        for item in page.get("products", []):
            print(item["sku"], item.get("name"))

Async Page Streaming

async with AsyncBestBuyAPI() as bb:
    async for page in bb.stores.aiter_pages(query="region=MN", page_size=10, max_pages=3):
        for store in page.get("stores", []):
            print(store["storeId"], store["name"])

Error Handling

The library provides granular exception classes:

from bestbuyapi import BestBuyAPI
from bestbuyapi.utils.exceptions import (
    BestBuyAuthenticationError,
    BestBuyNotFoundError,
    BestBuyRateLimitError,
    BestBuyHTTPError,
    BestBuyValidationError,
)

try:
    with BestBuyAPI() as bb:
        bb.products.search_by_sku(12345)
except BestBuyAuthenticationError:
    print("Invalid or missing API key!")
except BestBuyRateLimitError:
    print("API rate limit exceeded. Please back off and retry.")
except BestBuyNotFoundError:
    print("Product not found.")
except BestBuyHTTPError as e:
    print(f"Best Buy HTTP Error ({e.status_code}): {e.message}")
except BestBuyValidationError as e:
    print(f"Invalid parameters: {e}")

Development

Running Tests

uv run pytest -v --cov=bestbuyapi --cov-report=term-missing

Pre-commit & Linting

uv run pre-commit run --all-files
uv run ruff check .
uv run ruff format --check .

FAQ

  • Is there any difference between api.bestbuy.com and api.remix.bestbuy.com? No, both serve the same data. api.bestbuy.com is the official consolidated endpoint used by this library.

  • Are bb.category and bb.categories both supported? Yes! bb.categories is an ergonomic alias for bb.category, and bb.buying_options is an alias for bb.open_box.


Questions or feedback? Feel free to open an issue or reach out at luis@lv10.me.

Metadata

Release files for bestbuyapi 2.2.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for bestbuyapi 2.2.0
File Size Uploaded Provenance
bestbuyapi-2.2.0.tar.gz 22.6 kB Without provenance Details

Built distribution (wheel)

Table of built distributions (wheels) for bestbuyapi 2.2.0
File Interpreter ABI Platform
bestbuyapi-2.2.0-py3-none-any.whl Python 3 none any Details

Total release size: 40.2 kB

Release files / bestbuyapi-2.2.0.tar.gz

Download URL bestbuyapi-2.2.0.tar.gz
Size 22.6 kB
Tags Source
SHA-256 checksum
How to use checksums
abb77b73795748e2878608f089b8f3827e4bbe6db45cd82e1fe15f9c0292fa00
BLAKE2b-256 checksum
How to use checksums
e227f3782ad440558d44b883a7359af60f4a185c2d549d702fd9e75f996f8e91
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.12.5 {"installer":{"name":"uv","version":"0.12.5","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Release files / bestbuyapi-2.2.0-py3-none-any.whl

Download URL bestbuyapi-2.2.0-py3-none-any.whl
Size 17.6 kB
Tags Python 3
SHA-256 checksum
How to use checksums
61d5c66c083b02c06f1fefa412e9b9da593c3ec71bd725fa96a2178cf38e437b
BLAKE2b-256 checksum
How to use checksums
c5f15c7c48467b6f856e836ea730bf695457aba89629fcd3a4224f678a88fa7f
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.12.5 {"installer":{"name":"uv","version":"0.12.5","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Security for bestbuyapi 2.2.0

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page