TyreReviews API

Access comprehensive tyre data, test results, and reviews programmatically

Rich Data

Access to 50,000+ tyres with scores, reviews, and test results

Fast & Reliable

Average response time under 100ms with 99.9% uptime

Secure

SSL encrypted, API key authentication, and rate limiting

Getting Started

Follow these simple steps to start using the TyreReviews API:

1. Get Your API Key

Contact our sales team to obtain your API credentials. You'll receive an API key, rate limit based on your plan, and access to documentation.

2. Make Your First Request

curl -X GET "https://api.tyrereviews.com/v1/tyres/search?pattern=michelin" \
  -H "X-API-Key: your_api_key_here"
Base URL

All API requests should be made to: https://api.tyrereviews.com/v1/

Authentication

The TyreReviews API uses API key authentication. Include your API key in the request header:

X-API-Key: your_api_key_here

Security Best Practices

Do
  • Keep your API key secure and private
  • Use environment variables to store keys
  • Rotate keys regularly
  • Use HTTPS for all requests
Don't
  • Share your API key publicly
  • Commit keys to version control
  • Include keys in client-side code
  • Use keys in URLs

Available Endpoints

Working Now: Search tyres, tyre details (with score breakdowns, confidence & mileage), score summary, score explanation, tyre tests, tyre reviews, tyre images, tyre alternatives, list tests, test details, test results, list brands, brand details, brand tyres

Tyre Endpoints

GET /tyres/search Search by pattern, brand, season, score
GET /tyres/{id} Full details with score breakdown & mileage
GET /tyres/{id}/score Overall score, confidence tier, source
GET /tyres/{id}/score-explanation Category breakdowns, methodology, narrative
GET /tyres/{id}/tests Professional test results with per-metric data
GET /tyres/{id}/reviews User reviews with ratings and statistics
GET /tyres/{id}/images Product images and YouTube videos
GET /tyres/{id}/alternatives Alternative search patterns

Test Endpoints

GET /tests List published magazine tests
GET /tests/{id} Test details with tyre list
GET /tests/{id}/results Full results with per-tyre metrics

Brand Endpoints

GET /brands All brands with tyre counts
GET /brands/{id} Brand details with stats
GET /brands/{id}/tyres Paginated brand tyre catalogue

Search Tyres

The search endpoint is the most powerful way to find tyres in our database.

Parameters

ParameterTypeDescription
patternstringSearch pattern (e.g., "michelin-pilot-sport")
brandstringFilter by brand name
seasonintegerSeason ID (1=summer, 2=winter, 3=all-season)
vehicleintegerVehicle type ID (1=Car, 2=SUV, 3=Van)
typeintegerTyre type ID
min_scorefloatMinimum score (0–10)
sortstringscore:desc (default), score:asc, name:asc, name:desc, views:desc, reviews:desc, date:desc
fieldsstringComma-separated field names (e.g., id,brand,model,score)
limitintegerResults per page (max 100)
offsetintegerPagination offset

Example Request

GET /v1/tyres/search?pattern=michelin&season=1&min_score=7&limit=10
X-API-Key: your_api_key_here

Example Response

{
  "success": true,
  "data": [
    {
      "id": 6,
      "tyre_id": "PS2",
      "brand_id": 3,
      "brand": "Michelin",
      "model": "Pilot Sport PS2",
      "full_name": "Michelin Pilot Sport PS2",
      "score": 7.8,
      "score_source": "combined",
      "review_count": 250,
      "avg_rating": 82.5,
      "season": "Summer",
      "vehicle_type": "Car",
      "tyre_type": "Performance",
      "image_url": "https://www.tyrereviews.com/images/tyres/Michelin-Pilot-Sport-PS2.jpg",
      "url": "https://www.tyrereviews.com/Tyre/Michelin/Pilot-Sport-PS2.htm"
    }
  ],
  "meta": { "total": 15, "count": 1, "limit": 10, "offset": 0 }
}
Pro Tip

Use either the numeric ID or a pattern string to get full tyre details:
GET /v1/tyres/6 (numeric ID) or GET /v1/tyres/pilot-sport-4 (pattern string)

Tyre Details

Get comprehensive information about a specific tyre, including score breakdowns, confidence, and expected mileage.

Request

GET /v1/tyres/3672
X-API-Key: your_api_key_here
Flexible Identifiers

The {id} parameter accepts both numeric IDs and pattern strings.
Numeric: /tyres/6 · Pattern: /tyres/pilot-sport-4 · URL encoded: /tyres/pilot%20sport%204

Patterns are matched against the tyre_alternative table and are case-insensitive.

Response Fields

FieldTypeDescription
idintegerUnique tyre identifier
brand_namestringManufacturer name
titlestringTyre model name
tyre_reviews_scorefloat|nullOverall score (0–10). Null if not calculated.
score_sourcestring|nullcombined, tests_only, or reviews_only
score_confidenceinteger|nullConfidence percentage (0–100)
score_confidence_tierstring|nullHigh (≥80%), Medium (≥50%), or Limited
season_namestringSeason type (Summer, Winter, All Season, All Weather)
vehicle_namestringTarget vehicle type
totalreviewsintegerNumber of user reviews
totalratingfloatAverage user rating (0–100)
image_urlstringFull URL to tyre product image
brand_image_urlstring|nullFull URL to brand logo
urlstringLink to the tyre page on tyrereviews.com
score_detailsobject|nullPre-computed category breakdown scores. See Tyre Scores.
expected_mileageobject|nullCombined mileage estimate from test data and user reviews.

Expected Mileage

When available, the expected_mileage object combines professional test mileage data with user-reported End-of-Life mileage (test data weighted 70%, user reviews 30%).

{
  "expected_mileage": {
    "has_data": true,
    "combined_mileage_miles": 32500,
    "combined_mileage_km": 52300,
    "confidence": "high",
    "has_discrepancy": false,
    "discrepancy_percent": 12,
    "test_data": {
      "confidence": "high",
      "avg_mileage_miles": 35000,
      "avg_mileage_km": 56327,
      "source_count": 2,
      "source_type": "test"
    },
    "user_data": {
      "confidence": "medium",
      "avg_mileage_miles": 28000,
      "avg_mileage_km": 45062,
      "source_count": 12,
      "source_type": "user_reviews"
    }
  }
}
FieldTypeDescription
combined_mileage_milesint|nullBest estimate in miles (test 70% + reviews 30%)
combined_mileage_kmint|nullBest estimate in kilometres
confidencestringhigh (both sources), medium (≥8 reviews), low (limited data)
has_discrepancyboolTrue when test and review mileage differ by more than 25%
test_dataobject|nullMileage from professional tests (breakdown_id 7)
user_dataobject|nullMileage from End-of-Life user reviews (min 3 reviews, 5k–100k miles)

Returns null if no mileage data is available from either source.

Tyre Scores

The Tyre Reviews Score is a composite 0–10 rating combining professional test data, user reviews, and consistency analysis using Bayesian statistical smoothing.

Score Summary: GET /tyres/{id}/score

GET /v1/tyres/3672/score
X-API-Key: your_api_key_here
{
  "success": true,
  "data": {
    "tyre_id": 3672,
    "overall_score": 7.2,
    "score_source": "combined",
    "confidence": 100,
    "confidence_tier": "High",
    "explanation_url": "/v1/tyres/3672/score-explanation"
  }
}

Category Breakdowns: score_details

When you fetch a tyre via GET /tyres/{id}, the response includes a score_details object:

{
  "score_details": {
    "categories": [
      { "name": "Snow", "display_score": 91.2, "raw_score": 98.0, "weight": 1.38, "test_count": 11 },
      { "name": "Wet", "display_score": 59.5, "raw_score": 91.9, "weight": 2.00, "test_count": 11 },
      { "name": "Dry", "display_score": 41.7, "raw_score": 89.4, "weight": 1.50, "test_count": 7 }
    ],
    "derived_categories": [
      { "name": "Traction", "display_score": 82.8, "raw_score": 96.2, "weight": 0, "test_count": 4 },
      { "name": "Braking", "display_score": 66.6, "raw_score": 90.0, "weight": 0, "test_count": 11 }
    ]
  }
}
FieldTypeDescription
display_scorefloatMin-max scaled score (0–100). Use for progress bars.
raw_scorefloatOriginal weighted average before scaling (0–100).
weightfloatCategory weight in overall score. Always 0 for derived.
test_countintNumber of test metrics contributing to this category.

Full Score Explanation: GET /tyres/{id}/score-explanation

Returns a comprehensive explanation including category breakdowns, methodology, source tests, and a narrative summary. Cached for 1 hour.

Availability

Returns 404 if the tyre has no score. Not all tyres have scores — approximately 1,946 tyres currently have computed scores.

Pattern Matching

All tyre endpoints accept flexible identifiers — you can use either numeric IDs or string patterns.

Pattern Matching Rules

The API tries to match your pattern in this order:

  1. Exact match on tyre_alternative.title
  2. Exact match on tyre_alternative.tyre_id
  3. Match with spaces converted to hyphens (case-insensitive)
  4. Match with all spaces removed (case-insensitive)

Examples

You SendMatchesResult
6Numeric IDTyre ID: 6
pilot sport 4PILOT SPORT 4Tyre ID: 1927
pilot-sport-4PILOT SPORT 4Tyre ID: 1927
Important
  • Patterns are case-insensitive
  • Spaces can be hyphens, plus signs, or URL encoded
  • Numeric IDs are faster (no database lookup required)

Test Endpoints

Access magazine tyre test data including test metadata, tyre positions, and detailed performance metrics.

Test Details: GET /tests/{id}

Returns full details for a specific published tyre test, including all tyres tested with their positions.

GET /v1/tests/450
X-API-Key: your_api_key_here

Response Fields

FieldTypeDescription
idintegerTest ID
titlestringFull test title
test_yearintegerYear the test was conducted
tyre_sizestringTyre size tested (e.g., "205/55 R16")
seasonstringSeason type
vehicle_typestringVehicle type
publication_idstring|nullPublishing source
tyres_testedintegerTotal tyres in the test
article_urlstringLink to article on tyrereviews.com
tyres[]arrayList of tyres with position, score, award, image_url

Example Response

{
  "success": true,
  "data": {
    "id": 450,
    "title": "Summer Tyre Test 2024",
    "test_year": 2024,
    "tyre_size": "205/55 R16",
    "season": "Summer",
    "vehicle_type": "Car",
    "tyres_tested": 10,
    "article_url": "https://www.tyrereviews.com/Article/summer-tyre-test-2024",
    "tyres": [
      {
        "tyre_id": 1927,
        "position": 1,
        "position_percentile": 100.0,
        "normalized_score": 95.2,
        "award": "Test Winner",
        "brand": "Michelin",
        "model": "Pilot Sport 5",
        "score": 8.1,
        "image_url": "https://www.tyrereviews.com/images/tyres/Michelin-Pilot-Sport-5.jpg"
      }
    ]
  }
}

Test Results: GET /tests/{id}/results

Returns the full results table with per-tyre performance metrics grouped by category.

ParameterTypeDescription
limitintegerResults per page (default 50, max 100)
offsetintegerPagination offset

Metrics Structure

The metrics object groups measurements by category. direction indicates whether lower or higher values are better.

{
  "metrics": {
    "Wet": [
      { "metric": "Wet Braking", "value": "34.2", "unit": "m", "direction": "lower" },
      { "metric": "Wet Handling", "value": "62.3", "unit": "s", "direction": "lower" }
    ],
    "Dry": [
      { "metric": "Dry Braking", "value": "33.8", "unit": "m", "direction": "lower" }
    ]
  }
}

Brand Endpoints

Access tyre brand information and browse brand catalogues.

Brand Details: GET /brands/{id}

FieldTypeDescription
idintegerBrand ID
namestringBrand name
brand_tierstring|nullPremium, Mid-Range, Economy, or Budget
tyre_countintegerTotal active tyres
average_scorefloat|nullAverage score across scored tyres
scored_tyresintegerNumber of tyres with a computed score
image_urlstring|nullBrand logo URL

Brand Tyres: GET /brands/{id}/tyres

Paginated list of all tyres from a brand with scores, confidence, and classification.

ParameterTypeDescription
limitintegerResults per page (default 20, max 100)
offsetintegerPagination offset
sortstringscore:desc (default), score:asc, name:asc, name:desc, reviews:desc

Example Response

{
  "success": true,
  "data": [
    {
      "id": 1927,
      "tyre_id": "PS5",
      "model": "Pilot Sport 5",
      "score": 8.1,
      "score_source": "combined",
      "score_confidence": 95,
      "score_confidence_tier": "High",
      "review_count": 120,
      "avg_rating": 88.5,
      "season": "Summer",
      "vehicle_type": "Car",
      "tyre_type": "Performance",
      "image_url": "https://www.tyrereviews.com/images/tyres/Michelin-Pilot-Sport-5.jpg",
      "url": "https://www.tyrereviews.com/Tyre/Michelin/Pilot-Sport-5.htm"
    }
  ],
  "meta": { "total": 85, "count": 10, "limit": 10, "offset": 0 }
}

Code Examples

# Search for tyres
curl -X GET "https://api.tyrereviews.com/v1/tyres/search?pattern=continental&season=2" \
  -H "X-API-Key: your_api_key_here"

# Get tyre details (includes score_details & expected_mileage)
curl -X GET "https://api.tyrereviews.com/v1/tyres/3672" \
  -H "X-API-Key: your_api_key_here"

# Get tyre by pattern string
curl -X GET "https://api.tyrereviews.com/v1/tyres/pilot-sport-4" \
  -H "X-API-Key: your_api_key_here"

# Get score summary
curl -X GET "https://api.tyrereviews.com/v1/tyres/3672/score" \
  -H "X-API-Key: your_api_key_here"

# Get full score explanation
curl -X GET "https://api.tyrereviews.com/v1/tyres/3672/score-explanation" \
  -H "X-API-Key: your_api_key_here"

# Get test details
curl -X GET "https://api.tyrereviews.com/v1/tests/450" \
  -H "X-API-Key: your_api_key_here"

# Get test results with metrics
curl -X GET "https://api.tyrereviews.com/v1/tests/450/results" \
  -H "X-API-Key: your_api_key_here"

# Get brand details
curl -X GET "https://api.tyrereviews.com/v1/brands/3" \
  -H "X-API-Key: your_api_key_here"

# Get brand tyres sorted by score
curl -X GET "https://api.tyrereviews.com/v1/brands/3/tyres?sort=score:desc&limit=10" \
  -H "X-API-Key: your_api_key_here"
const API_KEY = 'your_api_key_here';
const BASE_URL = 'https://api.tyrereviews.com/v1';
const headers = { 'X-API-Key': API_KEY };

async function searchTyres(pattern, season) {
  const res = await fetch(
    `${BASE_URL}/tyres/search?pattern=${pattern}&season=${season}`,
    { headers }
  );
  return res.json();
}

async function getTyreDetails(tyreId) {
  const res = await fetch(`${BASE_URL}/tyres/${tyreId}`, { headers });
  return res.json();
}

async function getScoreExplanation(tyreId) {
  const res = await fetch(`${BASE_URL}/tyres/${tyreId}/score-explanation`, { headers });
  return res.json();
}

// Display category scores
getTyreDetails(3672).then(({ data }) => {
  if (data.score_details) {
    data.score_details.categories.forEach(cat => {
      console.log(`${cat.name}: ${cat.display_score}% (${cat.test_count} tests)`);
    });
  }
});
import requests

API_KEY = 'your_api_key_here'
BASE_URL = 'https://api.tyrereviews.com/v1'
headers = {'X-API-Key': API_KEY}

def search_tyres(pattern, season=None, min_score=None):
    params = {'pattern': pattern}
    if season: params['season'] = season
    if min_score: params['min_score'] = min_score
    return requests.get(f'{BASE_URL}/tyres/search', headers=headers, params=params).json()

def get_tyre_details(tyre_id):
    return requests.get(f'{BASE_URL}/tyres/{tyre_id}', headers=headers).json()

# Display category breakdowns
tyre = get_tyre_details(3672)
details = tyre['data'].get('score_details')
if details:
    for cat in details['categories']:
        print(f"  {cat['name']}: {cat['display_score']}% ({cat['test_count']} tests)")
<?php
$apiKey = 'your_api_key_here';
$baseUrl = 'https://api.tyrereviews.com/v1';

function apiRequest($endpoint, $params = []) {
    global $apiKey, $baseUrl;
    $url = $baseUrl . $endpoint;
    if ($params) $url .= '?' . http_build_query($params);
    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, $url);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_HTTPHEADER, ['X-API-Key: ' . $apiKey]);
    $response = curl_exec($ch);
    curl_close($ch);
    return json_decode($response, true);
}

$results = apiRequest('/tyres/search', ['pattern' => 'michelin', 'season' => 1]);
foreach ($results['data'] as $tyre) {
    echo $tyre['full_name'] . " - Score: " . $tyre['score'] . "\n";
}

Error Handling

The API uses standard HTTP status codes:

CodeMeaningDescription
200OKRequest successful
400Bad RequestInvalid parameters or malformed request
401UnauthorizedInvalid or missing API key
404Not FoundResource not found
429Too Many RequestsRate limit exceeded
500Server ErrorInternal server error

Error Response Format

{
  "success": false,
  "message": "Invalid API key",
  "errors": ["The provided API key is not valid or has been suspended"],
  "meta": {
    "timestamp": "2026-01-19T10:30:00Z",
    "request_id": "550e8400-e29b-41d4-a716-446655440000"
  }
}
Common Issues
  • Empty results? Check spelling (e.g., "Pirelli" not "Prelli")
  • 404 on /tyres/{pattern}? Pattern not found — try searching first or use numeric ID
  • 401 Unauthorized? Check your API key in the X-API-Key header

Rate Limits

Rate limits are enforced based on your subscription plan:

Basic

  • 100 requests/hour
  • 10,000 requests/month
  • 1 year historical data

Enterprise

  • 10,000+ requests/hour
  • Unlimited requests
  • Custom endpoints + SLA

Rate Limit Headers

X-RateLimit-Limit: 1000
X-RateLimit-Remaining: 950
X-RateLimit-Reset: 1705665600

Best Practices

Caching

  • Cache responses locally when possible
  • Respect cache headers in responses
  • Tyre details change infrequently
  • Test results are static once published

Retries

  • Implement exponential backoff
  • Retry on 5xx errors only
  • Don't retry on 4xx errors
  • Maximum 3 retry attempts
Pro Tip

Use the fields parameter to request only specific fields and reduce response size:
GET /tyres/search?pattern=michelin&fields=id,brand,model,score

Support

We're here to help you integrate with the TyreReviews API.

Email Support

api@tyrereviews.com

Documentation

Comprehensive guides and API reference

Enterprise SLA

24-hour response, dedicated account manager