Discover/Finish Line API
live

Finish Line APIfinishline.com

Access Finish Line sneaker catalog data via 6 endpoints: search products, browse categories, get release dates, product details, store locations, and suggestions.

Endpoints
6
Updated
2mo ago

What is the Finish Line API?

The Finish Line API covers 6 endpoints that expose product search, category browsing, sneaker release calendars, and store locations from finishline.com. The search_products endpoint returns paginated results with fields including price, original_price, brand, color, rating, and review_count. The get_product_details endpoint goes further, returning SKU-level stock_level values (HIGH, LOW, OOS, UNKNOWN) and available sizes for any product detail page URL.

Try it
Page number (0-based)
Max results per page
Search keyword (e.g. 'Jordan', 'Nike Dunk')
api.parse.bot/scraper/de510481-7bb5-4661-9ec5-2884b255e511/<endpoint>
Ready to send
Fill in the parameters and hit sign in to send to see live response data here.
Call it over HTTPgrab a free API key at signup
curl -X GET 'https://api.parse.bot/scraper/de510481-7bb5-4661-9ec5-2884b255e511/search_products?page=0&limit=3&query=Jordan' \
  -H 'X-API-Key: $PARSE_API_KEY'
Python SDK · recommended

Typed, relational, agent-ready

A generated client with real types, enums, and the links between objects — the structure a flat JSON response can't carry. Autocompletes in your editor and reads cleanly to coding agents.

  • Fully typed · autocompletes
  • Objects link to objects
  • Typed errors & pagination

Typed Python client. Set up the SDK in your uv project, then pull this API’s typed client:

uv add parse-sdk
uv run parse init
uv run parse add --marketplace finishline-com-api

uv run parse add --marketplace pulls a pinned snapshot of this canonical API — it won’t change underneath you. To customize it, subscribe and swap to your own copy.

"""
Finish Line API Parser Client

A practical example for extracting product data, inventory, and release information
from Finish Line using the Parse API.

Get your API key from: https://parse.bot/settings
"""

import os
import requests
from typing import Optional, List, Dict, Any
from datetime import datetime


class ParseClient:
    """Client for interacting with the Finish Line Parse API."""

    def __init__(self, api_key: Optional[str] = None):
        """
        Initialize the Parse client.

        Args:
            api_key: API key for authentication. Falls back to PARSE_API_KEY env var.
        """
        self.base_url = "https://api.parse.bot"
        self.scraper_id = "de510481-7bb5-4661-9ec5-2884b255e511"
        self.api_key = api_key or os.getenv("PARSE_API_KEY")

        if not self.api_key:
            raise ValueError("API key must be provided or set in PARSE_API_KEY environment variable")

    def _call(self, endpoint: str, method: str = "POST", **params) -> Any:
        """
        Make a request to the Parse API.

        Args:
            endpoint: The endpoint name (e.g., 'search_products')
            method: HTTP method ('GET' or 'POST')
            **params: Query or body parameters

        Returns:
            JSON response from the API
        """
        url = f"{self.base_url}/scraper/{self.scraper_id}/{endpoint}"
        headers = {
            "X-API-Key": self.api_key,
            "Content-Type": "application/json"
        }

        try:
            if method == "GET":
                response = requests.get(url, headers=headers, params=params)
            elif method == "POST":
                response = requests.post(url, headers=headers, json=params)
            else:
                raise ValueError(f"Unsupported HTTP method: {method}")

            response.raise_for_status()
            return response.json()
        except requests.exceptions.RequestException as e:
            print(f"API Error: {e}")
            raise

    def search_products(
        self,
        query: str,
        page: int = 0,
        limit: int = 20
    ) -> Dict[str, Any]:
        """
        Search for products by keyword.

        Args:
            query: Search keyword (e.g., 'Jordan', 'Nike')
            page: Page number for pagination (default: 0)
            limit: Max results to return (default: 20)

        Returns:
            Dictionary with hits, total_hits, total_pages, and page
        """
        return self._call("search_products", method="GET", query=query, page=page, limit=limit)

    def get_product_details(self, url: str) -> Dict[str, Any]:
        """
        Fetch detailed product information from a PDP URL.

        Args:
            url: Full URL of the product detail page

        Returns:
            Dictionary with product details including name, price, sizes, colors, description
        """
        return self._call("get_product_details", method="GET", url=url)

    def get_search_suggestions(self, query: str) -> List[Dict[str, Any]]:
        """
        Get search autocomplete suggestions and product previews.

        Args:
            query: Partial search term

        Returns:
            List of suggestions with name, image, and url
        """
        return self._call("get_search_suggestions", method="GET", query=query)

    def get_sneaker_releases(self) -> Dict[str, Any]:
        """
        Retrieve upcoming sneaker release dates and details.

        Returns:
            Dictionary with releases array containing upcoming releases
        """
        return self._call("get_sneaker_releases", method="GET")

    def get_store_locator(
        self,
        query: Optional[str] = None,
        lat: Optional[str] = None,
        lng: Optional[str] = None
    ) -> List[Dict[str, Any]]:
        """
        Search for physical store locations by city name or geolocation.

        Args:
            query: City name to search near
            lat: Latitude for geolocation search
            lng: Longitude for geolocation search

        Returns:
            List of store locations with details
        """
        params = {}
        if query:
            params["query"] = query
        if lat:
            params["lat"] = lat
        if lng:
            params["lng"] = lng

        return self._call("get_store_locator", method="GET", **params)

    def get_product_listing_page(
        self,
        category_slug: str,
        page: int = 0,
        limit: int = 20
    ) -> Dict[str, Any]:
        """
        Browse products by category.

        Args:
            category_slug: Category identifier (e.g., 'mens-shoes', 'womens-shoes')
            page: Page number for pagination (default: 0)
            limit: Max results to return (default: 20)

        Returns:
            Dictionary with hits array and total count
        """
        return self._call(
            "get_product_listing_page",
            method="GET",
            category_slug=category_slug,
            page=page,
            limit=limit
        )


def main():
    """Demonstrate a practical workflow using the Finish Line API."""
    
    # Initialize the client
    client = ParseClient()
    print("✓ Connected to Finish Line API Parser\n")

    # Workflow: Search for sneakers, get details, find local stores, check releases
    print("=" * 80)
    print("WORKFLOW: Sneaker Search → Inventory Check → Store Locator → Release Calendar")
    print("=" * 80)

    # Step 1: Search for Jordan shoes
    print("\n[1/5] Searching for 'Jordan basketball shoes'...")
    search_results = client.search_products(query="Jordan basketball shoes", limit=5)
    
    if not search_results.get("hits"):
        print("No results found.")
        return

    total_hits = search_results.get("total_hits", 0)
    total_pages = search_results.get("total_pages", 0)
    current_page = search_results.get("page", 0)
    
    print(f"✓ Found {total_hits} results across {total_pages} pages")
    print(f"  Showing page {current_page} with {len(search_results['hits'])} items\n")

    # Step 2: Analyze top 2 products with detailed inventory info
    print("[2/5] Fetching inventory and detailed specs for top 2 products...\n")
    selected_products = []

    for idx, product in enumerate(search_results["hits"][:2], 1):
        product_name = product.get("name", "Unknown")
        product_url = product.get("url")
        product_price = product.get("price", "N/A")
        brand = product.get("brand", "Unknown")
        color = product.get("color", "Multiple")
        rating = product.get("rating", "N/A")
        review_count = product.get("review_count", 0)
        style_code = product.get("style_code", "")

        print(f"  Product {idx}: {product_name}")
        print(f"    Brand: {brand} | Style: {style_code}")
        print(f"    Price: ${product_price} | Color: {color}")
        print(f"    Rating: {rating}/5 ({review_count} reviews)")

        if product_url:
            try:
                details = client.get_product_details(url=product_url)
                selected_products.append({
                    "name": product_name,
                    "price": product_price,
                    "url": product_url,
                    "details": details
                })

                # Display size availability
                if details.get("sizes"):
                    sizes_data = details["sizes"]
                    in_stock = [s.get("size") for s in sizes_data if s.get("stock_level") != "OOS"]
                    print(f"    ✓ Available sizes: {', '.join(in_stock[:10])}")
                    
                    # Count stock levels
                    stock_summary = {}
                    for size in sizes_data:
                        level = size.get("stock_level", "UNKNOWN")
                        stock_summary[level] = stock_summary.get(level, 0) + 1
                    print(f"    Stock levels: {', '.join([f'{k}={v}' for k, v in stock_summary.items()])}")
                
                # Display color options
                if details.get("colors"):
                    colors_list = [c.get("name") for c in details["colors"][:3]]
                    print(f"    ✓ Colors: {', '.join(colors_list)}")
                        
            except Exception as e:
                print(f"    ✗ Could not fetch details: {str(e)}")
            
            print()

    # Step 3: Get related product suggestions
    print("[3/5] Getting search suggestions for 'Nike Air'...\n")
    suggestions = client.get_search_suggestions(query="Nike Air")
    
    if suggestions and isinstance(suggestions, list):
        print(f"✓ Found {len(suggestions)} related product suggestions:")
        for suggestion in suggestions[:3]:
            sugg_name = suggestion.get("name", "Unknown")
            print(f"  • {sugg_name}")
        print()

    # Step 4: Find nearby stores in Chicago
    print("[4/5] Locating Finish Line stores in Chicago...\n")
    stores = client.get_store_locator(query="Chicago")
    
    if stores and isinstance(stores, list):
        print(f"✓ Found {len(stores)} store(s):\n")
        for store in stores[:3]:
            store_name = store.get("name", "Store")
            city = store.get("city", "Unknown")
            state = store.get("state", "")
            zip_code = store.get("zip", "")
            store_id = store.get("store_id", "")
            
            print(f"  Store ID: {store_id} | {store_name}")
            print(f"  Location: {city}, {state} {zip_code}\n")
    else:
        print("No stores found in that area.\n")

    # Step 5: Check upcoming sneaker releases
    print("[5/5] Checking upcoming sneaker releases...\n")
    releases = client.get_sneaker_releases()
    
    if releases and releases.get("releases"):
        total_releases = releases.get("total", 0)
        print(f"✓ Found {total_releases} total releases in calendar\n")
        
        # Show upcoming (not yet released) releases
        upcoming = [r for r in releases["releases"] if not r.get("released", False)][:4]
        
        if upcoming:
            print(f"Next {len(upcoming)} upcoming releases:\n")
            for release in upcoming:
                rel_name = release.get("name", "Unknown")
                rel_date = release.get("release_date", "TBA")
                rel_price = release.get("price", "N/A")
                brand = release.get("brand", "Unknown")
                color = release.get("color", "Multiple")
                exclusive = release.get("exclusive_access", False)
                
                # Format release date
                try:
                    dt = datetime.fromisoformat(rel_date.replace("Z", "+00:00"))
                    formatted_date = dt.strftime("%B %d, %Y at %I:%M %p")
                except (ValueError, AttributeError):
                    formatted_date = rel_date
                
                exclusive_label = " [EXCLUSIVE ACCESS]" if exclusive else ""
                print(f"  • {brand} {rel_name}{exclusive_label}")
                print(f"    Release: {formatted_date}")
                print(f"    Price: ${rel_price} | Color: {color}\n")
        else:
            print("No upcoming releases scheduled.\n")

    # Step 6: Browse a category
    print("[Bonus] Browsing 'mens-shoes' category...\n")
    category_results = client.get_product_listing_page(category_slug="mens-shoes", limit=3)
    
    if category_results and category_results.get("hits"):
        total = category_results.get("total", 0)
        page_count = category_results.get("total_pages", 0)
        print(f"✓ Found {total} men's shoes across {page_count} pages\n")
        print("Sample items from category:\n")
        
        for item in category_results["hits"][:3]:
            item_name = item.get("name", "Unknown")
            item_price = item.get("price", "N/A")
            item_brand = item.get("brand", "Unknown")
            item_rating = item.get("rating", "N/A")
            print(f"  • {item_brand} {item_name}")
            print(f"    ${item_price} | Rating: {item_rating}/5\n")

    print("=" * 80)
    print("✓ Workflow completed successfully!")
    print("=" * 80)


if __name__ == "__main__":
    main()
All endpoints · 6 totalmissing one? ·

Search for products by keyword. Returns paginated product results with names, prices, images, brands, and URLs.

Input
ParamTypeDescription
pageintegerPage number (0-based)
limitintegerMax results per page
queryrequiredstringSearch keyword (e.g. 'Jordan', 'Nike Dunk')
Response
{
  "type": "object",
  "fields": {
    "hits": "array of product objects with product_id, style_code, name, price, original_price, image_url, url, brand, color, rating, review_count",
    "page": "integer current page number",
    "total_hits": "integer total number of matching products",
    "total_pages": "integer total number of pages"
  },
  "sample": {
    "data": {
      "hits": [
        {
          "url": "https://www.finishline.com/pdp/mens-air-jordan-retro-5-basketball-shoes/prod2799959/HQ7978/103",
          "name": "Men's Air Jordan Retro 5 Basketball Shoes",
          "brand": "Jordan",
          "color": "White/Metallic Silver/Black",
          "price": 215,
          "rating": 5,
          "image_url": "https://media.finishline.com/s/finishline/HQ7978_103?$Main$",
          "product_id": "prod2799959",
          "style_code": "HQ7978-103",
          "review_count": 781,
          "original_price": 215
        }
      ],
      "page": 0,
      "total_hits": 631,
      "total_pages": 211
    },
    "status": "success"
  }
}

About the Finish Line API

Product Search and Browsing

The search_products endpoint accepts a query string (e.g., 'Jordan' or 'Nike Dunk') and returns paginated hits with fields including product_id, style_code, name, price, original_price, image_url, url, brand, color, rating, and review_count. Pagination is 0-based via the page and limit parameters. The get_product_listing_page endpoint mirrors this response shape but navigates by category slug — accepted slugs include mens-shoes, womens-clothing, boys-shoes, and similar category-level paths — making it straightforward to enumerate a full category.

Product Details and Inventory

get_product_details takes the full PDP URL returned in any hits[*].url field and returns a richer record: a sizes array with each entry carrying a size, sku, and stock_level (one of HIGH, LOW, OOS, or UNKNOWN), a colors array with style_color and name, a description string, and final and original prices. This is the primary endpoint for inventory checking at the SKU level.

Sneaker Releases and Suggestions

get_sneaker_releases requires no inputs and returns up to 50 entries from the release calendar. Each release object includes name, style_code, price, original_price, brand, release_date, released (boolean), launch type, and exclusive_access flag. The get_search_suggestions endpoint takes a partial query string and returns up to 5 preview objects, each with a name, image URL, and url — useful for typeahead interfaces or quickly resolving a style name to a PDP URL.

Store Locator

get_store_locator accepts either a city name via query or geographic coordinates via lat and lng. It returns up to 20 store records with store_id, name, city, state, zip, lat, and lng. This covers physical Finish Line retail locations in the US.

Reliability & maintenance

The Finish Line API is a managed, monitored endpoint for finishline.com — not a raw scraper you maintain. Every endpoint is automatically health-checked on a schedule, and when finishline.com changes and a check fails, the API is automatically queued for repair and re-verified. It is built to keep working as the site underneath it changes.

This isn't an official finishline.com API — it's an independent, maintained REST wrapper over public data. Where the source has no official API (or only a limited one), Parse gives you a stable contract over a source that never promised one, and keeps it current. Need a new endpoint or field? You can revise it yourself in plain English and the agent rebuilds it against the live site in minutes — contributing the change back to the shared API is free.

Will this API break when the source site changes?+
It's built not to. Every endpoint is health-checked on a schedule with automated test probes. When the source site changes and a check fails, the API is automatically queued for repair and re-verified — that's the self-healing layer. Each API page shows when its endpoints were last verified. And because marketplace APIs are shared, any fix reaches everyone using it.
Is this an official API from the source site?+
No — Parse APIs are independent, managed REST wrappers over publicly available data. That is the point: where a site has no official API (or only a limited one), Parse gives you a maintained, monitored endpoint for that data and keeps it working as the site changes — so you get a stable contract over a source that never promised one.
Can I fix or extend this API myself if I need a new endpoint or field?+
Yes — and you don't have to wait on us. This API was generated by the Parse agent, which stays attached. Describe the change in plain English ("add an endpoint that returns reviews", "fix the price field") in the revise box on the API page or via the revise_api MCP tool, and the agent rebuilds it against the live site in minutes. Contributing the change back to the public API is free.
What happens if I call an endpoint that has an issue?+
Errors are machine-readable: a bad call returns a clean status with the list of available endpoints and a repair hint, so an agent (or you) can recover or trigger a fix instead of failing silently. Confirmed failures feed the automatic repair queue.
Common use cases
  • Monitor sneaker release dates and exclusive_access flags from the release calendar to alert users before a drop.
  • Build a price-drop tracker by comparing price vs original_price across category pages using get_product_listing_page.
  • Check real-time size availability and SKU-level stock_level for a specific shoe using get_product_details.
  • Power a sneaker search autocomplete feature using get_search_suggestions with partial query input.
  • Aggregate brand and colorway inventory by scraping brand and color fields from search_products for a given keyword.
  • Find the nearest Finish Line retail location by passing GPS coordinates to get_store_locator.
  • Compile a release calendar feed with style_code, brand, price, and release_date for reseller or enthusiast platforms.
Pricing & limitsSee full pricing →
TierPriceCredits/monthRate limit
Free$0/mo1005 req/min
Hobby$30/mo1,00020 req/min
Developer$100/mo5,000100 req/min

One credit = one API call regardless of which marketplace API you call. Exceeding the rate limit returns a 429 response. Authenticate with the X-API-Key header.

Frequently asked questions
Does Finish Line have an official public developer API?+
No. Finish Line does not publish a public developer API or API documentation for third-party access to its catalog or store data.
What stock level values does `get_product_details` return, and what do they mean?+
The sizes array returns one of four stock_level strings per SKU: HIGH (ample inventory), LOW (limited stock remaining), OOS (out of stock), or UNKNOWN (status not determinable). This is per-size and per-SKU, not an aggregate product-level flag.
How many sneaker releases does `get_sneaker_releases` return, and can it be filtered by brand or date?+
The endpoint returns up to 50 releases from the calendar and takes no filter inputs — it cannot be filtered by brand, date range, or release status directly. Each result does include brand, release_date, and a released boolean, so filtering can be applied client-side. You can fork the API on Parse and revise it to add server-side filter parameters.
Does the API include user reviews or review text?+
Not currently. Both search_products and get_product_listing_page return rating and review_count fields, but individual review text and reviewer details are not exposed by any endpoint. You can fork the API on Parse and revise it to add a review-fetching endpoint.
What happens if I pass both `query` and `lat`/`lng` to `get_store_locator`?+
The endpoint accepts either a city name via query or geographic coordinates via lat and lng. If both are provided, results reflect whichever the source resolves first — for predictable results, use one input method at a time. The endpoint returns up to 20 stores regardless of input method.
Page content last updated . Spec covers 6 endpoints from finishline.com.
Related APIs in EcommerceSee all →
footlocker.com API
Access product listings, pricing, availability, customer reviews, release calendars, and category/brand browsing data from Foot Locker.
sneakers.com API
Search and browse sneaker products across categories and brands, view detailed product information, and discover current flash sales and trending searches from sneakers.com. Get instant access to sneaker listings, pricing, and real-time sale events to find exactly what you're looking for.
nike.com API
Search the Nike product catalog by keyword and retrieve detailed product information including pricing, sizing, color variants, and availability. Use autocomplete suggestions to refine queries and discover relevant products on Nike.com.
stockx.com API
Search and browse StockX products to access detailed pricing, market trends, and historical sales data all in one place. Compare sneaker and streetwear prices across listings, track price history, and discover product information to stay informed on the resale market.
stadiumgoods.com API
Search and discover premium sneakers and streetwear from Stadium Goods. Retrieve detailed product specifications, variant-level pricing, and real-time inventory status across the full catalog and curated collections.
sneakernews.com API
Browse the latest sneaker news, search articles by keyword, and look up upcoming release dates — including pricing, images, and retailer links. Also surfaces per-page ad slot inventory and density metrics for programmatic and publisher analysis.
nike.com.cn API
Search Nike China's catalog to find products, check availability, browse specific categories like men's, women's, and kids' shoes, and discover trending items and new arrivals. Get detailed product information including sizes, pricing, and specifications to help with shopping decisions and market research.
adidas.de API
Search and browse Adidas products on adidas.de to find detailed information about items, availability, pricing, and specific categories. Get comprehensive product details including size availability and stock levels across the German Adidas store.