Core Phone API Documentation

Back to Price Search

API Base URL

Endpoints use different base paths. Refer to the specific endpoint URL below.

Overview

This documentation covers the core APIs for phone data ingestion, variant searching, and price estimation.

POST Ingest Phone Data (Single or Batch)

/api/v1/phones/ingest

Ingest a single phone's technical data (as JSON object) or multiple phones (as JSON array), normalize it, and store it in Elasticsearch. Performs an upsert based on SKU. This is the primary way to add or update phone variant specifications.

Parameters
Name Type Description
imei string Unique IMEI identifier for the phone (optional, but recommended for linking to specific devices)
brand string Brand name (e.g., Samsung, Apple)
model string Model name (e.g., Galaxy S25 Ultra, iPhone 15 Pro)
internal_memory integer Internal storage in MB (e.g., 256000 for 256GB) or GB (e.g., 256 for 256GB - heuristic applied)
ram integer RAM in MB (e.g., 12000 for 12GB) or GB (e.g. 12 for 12GB - heuristic applied)
colors string Available colors, comma-separated (primarily for initial seeding if original_color is not provided per variant later)
year_of_production string Production year (e.g., 2024). Defaults to current year if invalid/missing.
month_of_production string Production month (1-12). Defaults to '01' if invalid/missing.
(...other specs) various See example for other optional fields like physical dimensions, battery, connectivity, etc.
Responses
Code Description
201 Single phone data successfully ingested/updated
200 Batch processed successfully (all items succeeded)
207 Batch processed with partial success (Multi-Status)
400 Invalid request (bad JSON, missing fields, normalization error)
500 Server error during processing or storage
Example Request
Single Object:
{
  "imei": "354222650219092",
  "brand": "SAMSUNG",
  "model": "Galaxy S25 Ultra",
  "internal_memory": 256000,
  "ram": 12000,
  "colors": "Titanium Silver Blue, Titanium Black",
  "year_of_production": "2024",
  "month_of_production": "01",
  "_5g": true,
  "height": 162.8,
  "width": 77.6,
  "thickness": 8.2,
  "weight": 218,
  "certification": "IP68",
  "battery_type": "Li-Ion",
  "battery_capacity": 5000.0,
  "wireless_charging": true
}

Array for Batch:
[
  {
    "imei": "354222650219092",
    "brand": "SAMSUNG",
    "model": "Galaxy S25 Ultra",
    "internal_memory": 256000,
    "ram": 12000,
    "colors": "Titanium Silver Blue",
    "year_of_production": "2024", "month_of_production": "01"
  },
  {
    "imei": "358244958411136",
    "brand": "APPLE",
    "model": "iPhone 16 Pro",
    "internal_memory": 512000,
    "ram": 8000,
    "colors": "Natural Titanium",
    "year_of_production": "2024", "month_of_production": "09"
  }
]
Example Response
Single Success (201):
{
  "status": "success",
  "sku": "SAMSUNG_GALAXY_S25_ULTRA_256GB",
  "imei": "354222650219092"
}

Batch Success (200):
{
  "status": "success",
  "processed_count": 2,
  "success_count": 2,
  "results": [
    {"status": "success", "sku": "SAMSUNG_GALAXY_S25_ULTRA_256GB", "imei": "354222650219092"},
    {"status": "success", "sku": "APPLE_IPHONE_16_PRO_512GB", "imei": "358244958411136"}
  ]
}

Batch Partial Success (207):
{
  "status": "partial_success",
  "processed_count": 2,
  "success_count": 1,
  "results": [
    {"status": "success", "sku": "SAMSUNG_GALAXY_S25_ULTRA_256GB", "imei": "354222650219092"},
    {"status": "error", "error": "Normalization failed: Could not normalize storage...", "imei": "MISSING_IMEI"}
  ]
}

GET Search Product Variants (Get SKUs)

/api/search-variants

Search for product variants (which include SKUs) based on a query string. Useful for finding the SKUs needed for other API calls. Extracts storage from the query and searches text fields.

Parameters
Name Type Description
q string Query string (e.g., "iPhone 15 Pro 256gb", "samsung s24")
Responses
Code Description
200 Returns an array of matching product variant objects, each containing a 'sku'.
400 Missing query parameter 'q'
500 Internal server error during search
Example Request
curl -X GET "http://localhost:4000/api/search-variants?q=iphone+15+pro+256gb"
Example Response
[
  {
    "sku": "apple_iphone-15-pro_256gb",
    "brand": "Apple",
    "model": "iPhone 15 Pro",
    "storage": 256,
    "manufacturing_year": 2023,
    "release_date": "2023-09-22",
    "specs": { "...": "..." },
    "color": "Natural Titanium",
    "imei": null
  }
]

GET Get Price Estimate for SKUs

/api/price-search/price-estimate

Get price estimates for a list of SKUs broken down by condition. This is a key step after identifying SKUs via the search variants endpoint. Provides detailed price estimates including baseline data, confidence intervals, Kuusakoski wholesale prices, and AI-generated price estimates for each condition of the specified SKUs. Response includes: estimate (median price), min_estimate (10th percentile), max_estimate (90th percentile), wholesale_price (Kuusakoski maximum purchase price for applicable conditions), wholesale_fallback (true if estimate is based on wholesale price with retail markup), and ai_price (ML model prediction).

Parameters
Name Type Description
skus string Comma-separated list of product SKUs for which to get price estimates (e.g., 'apple_iphone-se_128,apple_iphone-se_256')
reference_date string Optional reference date in YYYY-MM-DD format. Defaults to current date if not provided
Responses
Code Description
200 Returns price estimates for each SKU with new structured format including SKU_Name and Conditions array
400 Invalid request (e.g., missing SKUs parameter or invalid reference_date format)
503 Elasticsearch service not available
500 Internal server error
Example Request
curl -X GET "http://localhost:4000/api/price-search/price-estimate?skus=apple_iphone-15-plus_128,apple_iphone-se_64&reference_date=2025-04-08"
Example Response
{
    "estimates_by_sku": [
        {
            "SKU_Name": "apple_iphone-15-plus_128",
            "Conditions": [
                {
                    "conditionName": "fair",
                    "conditionPrices": {
                        "baseline_count": 351,
                        "baseline_end_date": "2025-04-08",
                        "baseline_start_date": "2015-04-11",
                        "estimate": 734.82,
                        "max_estimate": 864.08,
                        "min_estimate": 664.17,
                        "wholesale_price": 150.00,
                        "wholesale_fallback": false,
                        "ai_price": 720.50
                    }
                },
                {
                    "conditionName": "good",
                    "conditionPrices": {
                        "baseline_count": 716,
                        "baseline_end_date": "2025-04-08",
                        "baseline_start_date": "2015-04-11",
                        "estimate": 764.65,
                        "max_estimate": 874.03,
                        "min_estimate": 685.1,
                        "wholesale_price": 220.00,
                        "wholesale_fallback": false,
                        "ai_price": 750.30
                    }
                },
                {
                    "conditionName": "mint",
                    "conditionPrices": {
                        "baseline_count": 1901,
                        "baseline_end_date": "2025-04-08",
                        "baseline_start_date": "2015-04-11",
                        "estimate": 844.2,
                        "max_estimate": 923.74,
                        "min_estimate": 724.87
                    }
                },
                {
                    "conditionName": "new",
                    "conditionPrices": {
                        "baseline_count": 3,
                        "baseline_end_date": "2025-04-08",
                        "baseline_start_date": "2015-04-11",
                        "estimate": 840.22,
                        "max_estimate": 883.17,
                        "min_estimate": 840.22
                    }
                }
            ]
        }
    ],
    "reference_date": "2025-04-08",
    "shared_erosion_rate": -0.0039
}

GET Get All Unique Colors

/api/colors

Retrieves all unique colors from product variants. Handles comma-separated color values and provides sorting options. Colors are extracted from the specs.physical_specs.colors field and normalized for consistency.

Parameters
Name Type Description
limit integer Maximum number of colors to return (1-10000, default: 1000)
sort string Sort order: 'alpha' for alphabetical, 'count' for frequency (default: 'alpha')
Responses
Code Description
200 Successfully retrieved colors list
400 Invalid parameters (limit out of range or invalid sort option)
500 Internal server error or Elasticsearch connection failure
Example Request
curl -X GET "http://localhost:4000/api/colors?limit=10&sort=count"
Example Response
{
  "colors": [
    "Black",
    "Blue", 
    "Gold",
    "Silver",
    "White"
  ],
  "total_count": 5,
  "sort_order": "count"
}

GET Get Color Statistics

/api/colors/stats

Provides detailed color statistics including frequency counts and percentages. Shows how many products have each color and their relative popularity.

Parameters
Name Type Description
limit integer Maximum number of colors to return (1-1000, default: 100)
Responses
Code Description
200 Successfully retrieved color statistics
400 Invalid limit parameter (out of range 1-1000)
500 Internal server error or Elasticsearch connection failure
Example Request
curl -X GET "http://localhost:4000/api/colors/stats?limit=5"
Example Response
{
  "colors": [
    {
      "color": "Black",
      "count": 525,
      "percentage": 39.68
    },
    {
      "color": "Blue", 
      "count": 301,
      "percentage": 22.75
    },
    {
      "color": "White",
      "count": 251,
      "percentage": 18.97
    }
  ],
  "total_unique_colors": 406,
  "total_variants": 1323,
  "returned_count": 3
}

GET Get All Unique SKUs

/api/skus

Retrieves all unique SKUs from product variants. Provides sorting options and allows filtering by limit. SKUs are extracted from the product_variants index and represent unique product identifiers.

Parameters
Name Type Description
limit integer Maximum number of SKUs to return (1-10000, default: 1000)
sort string Sort order: 'alpha' for alphabetical, 'count' for frequency (default: 'alpha')
Responses
Code Description
200 Successfully retrieved SKUs list
400 Invalid parameters (limit out of range or invalid sort option)
500 Internal server error or Elasticsearch connection failure
Example Request
curl -X GET "http://localhost:4000/api/skus?limit=10&sort=alpha"
Example Response
{
  "skus": [
    "apple_iphone-13_128",
    "apple_iphone-13_256",
    "apple_iphone-14_128",
    "samsung_galaxy-s21_128",
    "samsung_galaxy-s21_256"
  ],
  "total_count": 5,
  "sort_order": "alpha"
}

GET Get SKU Statistics

/api/skus/stats

Provides detailed SKU statistics including frequency counts and percentages. Shows how many variants exist for each SKU and their relative distribution in the database.

Parameters
Name Type Description
limit integer Maximum number of SKUs to return (1-1000, default: 100)
Responses
Code Description
200 Successfully retrieved SKU statistics
400 Invalid limit parameter (out of range 1-1000)
500 Internal server error or Elasticsearch connection failure
Example Request
curl -X GET "http://localhost:4000/api/skus/stats?limit=5"
Example Response
{
  "skus": [
    {
      "sku": "apple_iphone-13_128",
      "count": 1,
      "percentage": 0.21
    },
    {
      "sku": "samsung_galaxy-s21_256",
      "count": 1,
      "percentage": 0.21
    },
    {
      "sku": "google_pixel-6_128",
      "count": 1,
      "percentage": 0.21
    }
  ],
  "total_unique_skus": 466,
  "total_variants": 466,
  "returned_count": 3
}

GET Get Available Colors for an SKU

/api/v1/sku/<string:sku>/colors

Fetches unique pairs of (normalized_color, original_color) available for a given SKU. This helps in understanding color variations for a specific product variant.

Parameters
Name Type Description
sku string (in path) The product SKU (e.g., apple_iphone-15-pro_256gb)
Responses
Code Description
200 Returns a list of available color details for the SKU.
400 SKU parameter is missing or invalid.
404 SKU not found (implicitly, if no colors are returned, though the endpoint itself doesn't 404 for non-existent SKUs, just returns empty list).
500 Internal server error.
Example Request
curl -X GET "http://localhost:4000/api/v1/sku/apple_iphone-15-pro_256gb/colors"
Example Response
{
  "sku": "apple_iphone-15-pro_256gb",
  "color_details": [
    {
      "normalized_color": "blue",
      "original_color": "Natural Blue"
    },
    {
      "normalized_color": "white",
      "original_color": "Natural Titanium"
    }
  ]
}

GET Get Kuusakoski Price for a SKU

/api/kuusakoski/sku-price/<sku>

Retrieves Kuusakoski pricing information for a specific SKU. This provides the minimum stock price that Kuusakoski pays for phones, which should never be exceeded in purchase price estimates. Returns all pricing tiers (100%, 70%, 40%) along with the calculated minimum price.

Parameters
Name Type Description
sku string (in path) The product SKU to get pricing for (e.g., apple_iphone-11_128)
Responses
Code Description
200 Returns detailed pricing information for the SKU
404 SKU not found in Kuusakoski pricing data
500 Internal server error
Example Request
curl -X GET "http://localhost:4000/api/kuusakoski/sku-price/apple_iphone-11_128"
Example Response
{
  "sku": "apple_iphone-11_128",
  "brand": "APPLE",
  "model": "IPHONE 11",
  "storage": 128,
  "storage_unit": "gb",
  "manufacturing_year": 2019,
  "unit_amount": 31200,
  "pricing": {
    "kuusakoski_100_percent": 101.0,
    "kuusakoski_70_percent": 71.0,
    "kuusakoski_40_percent": 40.0,
    "minimum_price": 40.0
  },
  "created_at": "2025-01-12T10:30:00.000Z",
  "updated_at": "2025-01-12T10:30:00.000Z"
}

GET Search Kuusakoski Pricing Data

/api/kuusakoski/search

Search Kuusakoski pricing data with various filters. Allows filtering by brand, model, price range, manufacturing year, and storage capacity. Useful for finding pricing information for multiple products or analyzing pricing patterns.

Parameters
Name Type Description
brand string Filter by brand (e.g., APPLE, SAMSUNG)
model string Filter by model (partial match, case insensitive)
min_price number Minimum price filter (searches across all pricing tiers)
max_price number Maximum price filter (searches across all pricing tiers)
manufacturing_year integer Filter by manufacturing year
storage_min integer Minimum storage capacity
storage_max integer Maximum storage capacity
limit integer Maximum number of results (default: 20)
Responses
Code Description
200 Returns search results with pricing information
400 Invalid request parameters
500 Internal server error
Example Request
curl -X GET "http://localhost:4000/api/kuusakoski/search?brand=APPLE&manufacturing_year=2019&limit=5"
Example Response
{
  "total": 15,
  "count": 5,
  "items": [
    {
      "sku": "apple_iphone-11_64",
      "brand": "APPLE",
      "model": "IPHONE 11",
      "storage": 64,
      "storage_unit": "gb",
      "manufacturing_year": 2019,
      "unit_amount": 33491,
      "pricing": {
        "kuusakoski_100_percent": 92.0,
        "kuusakoski_70_percent": 64.0,
        "kuusakoski_40_percent": 37.0,
        "minimum_price": 37.0
      }
    }
  ]
}

POST Get Minimum Prices for Multiple SKUs

/api/kuusakoski/minimum-prices

Retrieves minimum Kuusakoski prices for a list of SKUs in a single request. This is the key endpoint for ensuring purchase price estimates never exceed Kuusakoski's minimum stock prices. Returns pricing information for found SKUs and identifies missing ones.

Parameters
Name Type Description
skus array List of SKUs to get minimum prices for
Responses
Code Description
200 Returns minimum prices for requested SKUs
400 Invalid request body or missing SKUs list
500 Internal server error
Example Request
curl -X POST "http://localhost:4000/api/kuusakoski/minimum-prices" \
-H "Content-Type: application/json" \
-d '{"skus": ["apple_iphone-11_128", "samsung_galaxy-s20_256", "unknown_sku"]}'
Example Response
{
  "requested_count": 3,
  "found_count": 2,
  "missing_count": 1,
  "missing_skus": ["unknown_sku"],
  "prices": {
    "apple_iphone-11_128": {
      "sku": "apple_iphone-11_128",
      "brand": "APPLE",
      "model": "IPHONE 11",
      "minimum_price": 40.0,
      "pricing_tiers": {
        "100_percent": 101.0,
        "70_percent": 71.0,
        "40_percent": 40.0
      }
    },
    "samsung_galaxy-s20_256": {
      "sku": "samsung_galaxy-s20_256",
      "brand": "SAMSUNG",
      "model": "GALAXY S20",
      "minimum_price": 25.0,
      "pricing_tiers": {
        "100_percent": 75.0,
        "70_percent": 50.0,
        "40_percent": 25.0
      }
    },
    "unknown_sku": {
      "sku": "unknown_sku",
      "minimum_price": null,
      "error": "SKU not found in Kuusakoski pricing data"
    }
  }
}

GET Get Kuusakoski Pricing Statistics

/api/kuusakoski/stats

Provides comprehensive statistics about the Kuusakoski pricing data including brand distribution, manufacturing year ranges, pricing tier statistics, and storage unit distribution. Useful for understanding the scope and quality of the pricing data.

Responses
Code Description
200 Returns detailed statistics about Kuusakoski pricing data
500 Internal server error
Example Request
curl -X GET "http://localhost:4000/api/kuusakoski/stats"
Example Response
{
  "total_records": 1289,
  "brands": {
    "count": 34,
    "top_brands": [
      {"brand": "SAMSUNG", "count": 314},
      {"brand": "NOKIA", "count": 171},
      {"brand": "XIAOMI", "count": 114}
    ]
  },
  "manufacturing_years": {
    "range": {"min": 1997, "max": 2025},
    "distribution": [
      {"year": 2019, "count": 99},
      {"year": 2020, "count": 156}
    ]
  },
  "storage_units": [
    {"unit": "gb", "count": 1205},
    {"unit": "mb", "count": 118}
  ],
  "pricing_statistics": {
    "100_percent_tier": {
      "count": 1289,
      "min": 2.0,
      "max": 838.0,
      "avg": 60.12
    },
    "70_percent_tier": {
      "count": 1289,
      "min": 2.0,
      "max": 587.0,
      "avg": 42.35
    },
    "40_percent_tier": {
      "count": 1289,
      "min": 2.0,
      "max": 335.0,
      "avg": 24.46
    }
  },
  "unit_amount_statistics": {
    "count": 1289,
    "min": 0.0,
    "max": 33491.0,
    "avg": 2634.56
  }
}