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:

  • API Key for authentication
  • Rate limit based on your plan
  • Access to documentation
2. Make Your First Request

Test your API key with a simple search:

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

The API provides the following endpoints for accessing tyre data:

Endpoint Status

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

GET /tyres/search

Search tyres using pattern matching with various filters

Parameter Type Description
pattern string Search pattern (e.g., "michelin-pilot-sport")
brand string Filter by brand name
season integer Season ID (1=summer, 2=winter, 3=all-season)
limit integer Results per page (max 100)
offset integer Pagination offset
vehicle integer Filter by vehicle type ID (e.g., 1=Car, 2=SUV, 3=Van)
type integer Filter by tyre type ID
min_score float Minimum tyre_reviews_score (0–10 scale)
sort string Sort order. Options: score:desc (default), score:asc, name:asc, name:desc, views:desc, reviews:desc, date:desc
fields string Comma-separated field names to include in response (e.g., id,brand,model,score)

GET /tyres/{id}

Get comprehensive details for a specific tyre

GET /tyres/{id}/score

Get overall score, confidence tier, and source type for a tyre

GET /tyres/{id}/score-explanation

Get full score explanation with category breakdowns (primary & derived), methodology, source tests, and narrative

GET /tyres/{id}/tests

Get all magazine test results for a specific tyre

GET /tyres/{id}/reviews

Get user reviews with ratings, review text, car info, and aggregate statistics. Supports sort=date:desc or sort=rating:desc.

GET /tyres/{id}/images

Get all media (product images and YouTube videos) associated with a tyre

GET /tyres/{id}/alternatives

Get all alternative search patterns for a tyre from the tyre_alternative table

GET /tests

List all published magazine tyre tests, ordered by year (newest first). Includes tyre count per test. Supports limit (default 20, max 100) and offset pagination parameters.

GET /brands

List all tyre brands with tyre counts and brand logos

Search Tyres

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

Pattern Matching

Our pattern matching system understands various formats:

  • michelin-pilot-sport-4 - Hyphenated format
  • michelin pilot sport 4 - Space separated
  • PS4 - Common abbreviations
  • 205/55R16 - Size patterns

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_id": 1,
      "season": "Summer",
      "vehicle_id": 1,
      "vehicle_type": "Car",
      "type_id": 1,
      "tyre_type": "Performance",
      "image": "Michelin-Pilot-Sport-PS2.jpg",
      "pattern_match": "Pilot Sport PS2",
      "alternative_id": "PS2",
      "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

Note the id field in the response. You can use either the numeric ID OR a pattern string to get full tyre details:

GET /v1/tyres/6 (numeric ID)
GET /v1/tyres/pilot-sport-4 (pattern string)

Tyre Details

Get comprehensive information about a specific tyre, including score breakdowns 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 ID: /tyres/6
Pattern (with hyphens): /tyres/pilot-sport-4
Pattern (URL encoded): /tyres/pilot%20sport%204

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

Response Fields

Field Type Description
id integer Unique tyre identifier
brand_name string Manufacturer name
title string Tyre model name
tyre_reviews_score float|null Overall Tyre Reviews Score (0–10). Null if no score calculated.
score_source string|null combined, tests_only, or reviews_only
season_name string Season type (Summer, Winter, All Season, All Weather)
vehicle_name string Target vehicle type (Car, SUV, Van, etc.)
totalreviews integer Number of user reviews
totalrating float Average user rating (0–100)
alternative_patterns string Comma-separated alternative search patterns
image_url string Full URL to the tyre product image
brand_image_url string|null Full URL to the brand logo image
url string Link to the tyre page on tyrereviews.com
score_details object|null Pre-computed category breakdown scores. See Tyre Scores section.
expected_mileage object|null Combined mileage estimate from test data and user reviews. See below.

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",
      "test_data": [
        {
          "mileage_km": 55000,
          "mileage_miles": 34175,
          "test_title": "All Season Tyre Test 2024",
          "test_url": "all-season-tyre-test-2024",
          "tyre_size": "205/55 R16"
        }
      ]
    },
    "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), with per-test details
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. All scores are pre-computed and stored in the database.

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

Returns the stored overall score, confidence, and data source.

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"
  }
}

Tyre Detail: score_details field

When you fetch a tyre via GET /tyres/{id}, the response includes a score_details object containing pre-computed category breakdowns from the tyre_score_categories table:

{
  "score_details": {
    "categories": [
      { "name": "Snow", "display_score": 91.2, "raw_score": 98.0, "weight": 1.38, "test_count": 11 },
      { "name": "Value", "display_score": 86.1, "raw_score": 91.8, "weight": 0.38, "test_count": 2 },
      { "name": "Ice", "display_score": 71.4, "raw_score": 89.9, "weight": 1.20, "test_count": 3 },
      { "name": "Comfort", "display_score": 62.6, "raw_score": 92.7, "weight": 0.29, "test_count": 3 },
      { "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 },
      { "name": "Handling", "display_score": 63.7, "raw_score": 95.7, "weight": 0, "test_count": 13 }
    ]
  }
}
FieldTypeDescription
display_scorefloatMin-max scaled score (0–100). Use this for progress bars and charts.
raw_scorefloatOriginal weighted average before min-max scaling (0–100).
weightfloatEffective category weight in the overall score calculation. Always 0 for derived categories.
test_countintNumber of individual test metrics that contributed to this category score.

Returns null if no category data has been computed for this tyre.

Category Types

Primary Categories

Grouped by test section (title_group). Each test metric belongs to exactly one primary category.

  • Wet — aquaplaning, wet braking, wet handling
  • Dry — dry braking, dry handling, lateral grip
  • Snow — snow braking, snow traction, snow handling
  • Ice — ice braking, ice traction, ice handling
  • Comfort — noise, ride comfort, rolling resistance
  • Value — mileage, wear
  • Off road — gravel, mud, sand, grass
Derived Categories

Computed by matching keywords in metric names across all primary categories. A single metric can contribute to both its primary category and one or more derived categories.

  • Braking — all metrics containing “braking” (Wet Braking + Dry Braking + Snow Braking + Ice Braking + Gravel Braking, etc.)
  • Handling — all metrics containing “handling” (Wet Handling + Dry Handling + Snow Handling + subjective variants, etc.)
  • Traction — all metrics containing “traction” (Ice Traction + Snow Traction + Grass Traction + Mud Traction, etc.)
Pre-computed Scores

All category scores are pre-computed during tyre score calculation and stored in the tyre_score_categories table. They are updated whenever a tyre's score is recalculated (batch or manual). No real-time computation is needed to serve these values.

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

Returns a comprehensive explanation of how a tyre's score was calculated, including category breakdowns, methodology, source tests, and a narrative summary. Cached for 1 hour.

GET /v1/tyres/3672/score-explanation X-API-Key: your_api_key_here

Response Structure

{
  "success": true,
  "data": {
    "tyre": {
      "id": 3672,
      "brand": "Continental",
      "model": "AllSeasonContact 2",
      "full_name": "Continental AllSeasonContact 2",
      "season": "All Season",
      "brand_tier": "Premium",
      "image_url": "https://www.tyrereviews.com/images/tyres/Continental-AllSeasonContact-2.jpg"
    },
    "score": {
      "value": 7.2,
      "max": 10,
      "source": "combined",
      "source_label": "Based on Professional Tests & User Reviews",
      "confidence": 100,
      "confidence_tier": "High",
      "confidence_label": "High confidence - based on extensive test data",
      "score_color": "good",
      "last_updated": "2026-01-30"
    },
    "components": {
      "test_data": {
        "weight_percent": 80,
        "description": "Results from professional tests conducted by independent publications",
        "test_count": 3,
        "publication_count": 3,
        "date_range": { "oldest": "October 2023", "newest": "September 2024" }
      },
      "user_reviews": {
        "weight_percent": 15,
        "description": "Feedback from verified tyre owners",
        "review_count": 14,
        "average_rating": 83.6,
        "minimum_required": 5
      },
      "consistency": {
        "weight_percent": 5,
        "description": "How consistently the tyre performs across different conditions"
      }
    },
    "categories": [
      {
        "name": "Snow",
        "score": 98.0,
        "weight": 1.38,
        "test_count": 11,
        "bar_percent": 98,
        "relative_performance": "excellent"
      },
      {
        "name": "Wet",
        "score": 91.9,
        "weight": 2.00,
        "test_count": 11,
        "bar_percent": 92,
        "relative_performance": "excellent"
      }
    ],
    "derived_categories": [
      {
        "name": "Traction",
        "score": 96.2,
        "weight": 0,
        "test_count": 4,
        "bar_percent": 96,
        "relative_performance": "excellent"
      },
      {
        "name": "Braking",
        "score": 90.0,
        "weight": 0,
        "test_count": 11,
        "bar_percent": 90,
        "relative_performance": "excellent"
      },
      {
        "name": "Handling",
        "score": 95.7,
        "weight": 0,
        "test_count": 13,
        "bar_percent": 96,
        "relative_performance": "excellent"
      }
    ],
    "strengths": [
      { "category": "Snow", "score": 98.0 },
      { "category": "Comfort", "score": 92.7 }
    ],
    "weaknesses": [
      { "category": "Dry", "score": 89.4 },
      { "category": "Ice", "score": 89.9 }
    ],
    "source_tests": [
      {
        "title": "All Season Tyre Test 2024",
        "publication": "Auto Bild",
        "date": "September 2024",
        "tyre_size": "205/55 R16",
        "position": 1,
        "total_tyres": 10,
        "metrics_count": 12
      }
    ],
    "methodology": {
      "summary": "The Tyre Reviews Score is a comprehensive rating combining professional test data with user reviews using Bayesian statistical smoothing.",
      "scoring_process": [
        { "step": 1, "title": "Test Data Collection", "description": "..." },
        { "step": 2, "title": "Metric Weighting", "description": "..." },
        { "step": 3, "title": "Component Combination", "description": "..." },
        { "step": 4, "title": "Bayesian Smoothing", "description": "..." },
        { "step": 5, "title": "Recency Weighting", "description": "..." }
      ],
      "key_parameters": {
        "component_weights": { "test_data": 0.8, "user_reviews": 0.15, "consistency": 0.05 },
        "bayesian_prior_score": 7.0,
        "bayesian_prior_weight": 3.0,
        "recency_decay_rate": 0.95,
        "min_tests_required": 3,
        "min_reviews_required": 5,
        "score_version": "1.8"
      }
    },
    "narrative_explanation": "The Continental AllSeasonContact 2 achieves a strong Tyre Reviews Score of 7.2/10 with high confidence, based on both professional tests and user reviews...",
    "score_history": [
      { "score": 7.2, "date": "2026-01-30", "version": "1.8", "reason": "Manual recalculation" }
    ]
  }
}

Response Fields Reference

FieldTypeDescription
tyreobjectBasic tyre identification: id, brand, model, season, brand tier, image URL
score.valuefloatOverall Tyre Reviews Score (0–10)
score.sourcestringcombined, tests_only, or reviews_only
score.confidenceintConfidence percentage (0–100)
score.confidence_tierstringHigh (≥80%), Medium (≥50%), or Limited
score.score_colorstringexcellent (≥8.0), good (≥6.5), average (≥5.0), poor
categories[]arrayPrimary category scores (Wet, Dry, Snow, Ice, Comfort, Value, Off road). Sorted by score descending.
categories[].scorefloatWeighted average score for this category (0–100)
categories[].weightfloatEffective weight used in overall score (includes seasonal adjustment)
categories[].bar_percentintScore rounded to integer for progress bar rendering (0–100)
categories[].relative_performancestringexcellent (≥80), strong (≥70), good (≥60), average (≥50), below_average
derived_categories[]arrayCross-category scores (Braking, Handling, Traction). Same shape as categories[]. Weight is always 0.
strengths[]arrayTop 2 primary categories by score
weaknesses[]arrayBottom 2 primary categories by score
componentsobjectWeight breakdown: test data, user reviews, consistency—each with weight percentage and supporting stats
source_tests[]arrayList of professional tests that contributed data, with publication, date, tyre size, position, and metrics count
methodology.summarystringOne-sentence methodology overview
methodology.scoring_process[]array5 steps: Test Data Collection, Metric Weighting, Component Combination, Bayesian Smoothing, Recency Weighting. Each has step, title, description.
methodology.key_parametersobjectCurrent config values: component_weights, bayesian_prior_score, bayesian_prior_weight, recency_decay_rate, min_tests_required, min_reviews_required, score_version
methodology.dynamic_weighting_explanationstringExplains how weights redistribute when data sources are missing (e.g., test-only or review-only)
narrative_explanationstringHuman-readable summary of the score and performance
score_history[]arrayLast 5 score changes with date, version, and reason
Availability

Returns 404 if the tyre has no score (insufficient test data or reviews). Not all tyres have scores—approximately 1,946 tyres currently have computed scores.

Database Table: tyre_score_categories

All category scores are pre-computed and stored in this table. This is the source of truth for both the API and the front-end.

CREATE TABLE tyre_score_categories ( id INT AUTO_INCREMENT PRIMARY KEY, tid INT UNSIGNED NOT NULL, -- FK to tyre.id (CASCADE delete) category VARCHAR(30) NOT NULL, -- e.g. 'Wet', 'Braking' category_type ENUM('primary','derived') NOT NULL DEFAULT 'primary', display_score DECIMAL(4,1) NOT NULL, -- Min-max scaled (0-100) raw_score DECIMAL(4,1) NOT NULL, -- Original weighted avg (0-100) weight DECIMAL(4,2) NOT NULL, -- Category weight (0 for derived) test_count INT NOT NULL DEFAULT 0, -- Number of metric samples updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, UNIQUE KEY (tid, category), KEY (category, display_score), KEY (category_type, category, display_score) );

Example Queries

-- Best summer tyres for wet performance SELECT t.id, tb.title AS brand, t.title, tsc.display_score, tsc.test_count FROM tyre_score_categories tsc JOIN tyre t ON tsc.tid = t.id JOIN tyrebrand tb ON t.pid = tb.id JOIN tyre_season ts ON t.tyre_season_id = ts.id AND ts.lang = 'en' WHERE tsc.category = 'Wet' AND ts.title = 'Summer' AND tsc.test_count >= 3 ORDER BY tsc.display_score DESC LIMIT 20; -- Best braking across all conditions SELECT t.id, tb.title AS brand, t.title, tsc.display_score, tsc.test_count FROM tyre_score_categories tsc JOIN tyre t ON tsc.tid = t.id JOIN tyrebrand tb ON t.pid = tb.id WHERE tsc.category = 'Braking' AND tsc.test_count >= 3 ORDER BY tsc.display_score DESC LIMIT 20; -- All category scores for a specific tyre SELECT category, category_type, display_score, raw_score, weight, test_count FROM tyre_score_categories WHERE tid = 3672 ORDER BY category_type, display_score DESC;

Pattern Matching

All tyre endpoints accept flexible identifiers - you can use either numeric IDs or string patterns!

How It Works

When you provide a string instead of a numeric ID, the API automatically looks it up in the tyre_alternative table. This table contains over 11,000 search patterns for tyres.

Pattern Matching Rules

The API tries to match your pattern in the following 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 Send Matches Pattern Result
6 Numeric ID (no lookup) Tyre ID: 6
pilot sport 4 PILOT SPORT 4 Tyre ID: 1927
pilot-sport-4 PILOT SPORT 4 Tyre ID: 1927
Pilot%20Sport%20PS2 Pilot Sport PS2 Tyre ID: 6

Using Patterns in URLs

# Works with any tyre endpoint GET /v1/tyres/pilot-sport-4 GET /v1/tyres/pilot-sport-4/score GET /v1/tyres/pilot-sport-4/tests GET /v1/tyres/pilot-sport-4/reviews GET /v1/tyres/pilot-sport-4/images GET /v1/tyres/pilot-sport-4/alternatives
Important Notes
  • Patterns are case-insensitive
  • Spaces can be hyphens (-), plus signs (+), or URL encoded (%20)
  • If a pattern isn't found, you'll get a 404 error with a descriptive message
  • Numeric IDs are faster (no database lookup required)

Code Examples

Examples in popular programming languages:

# 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 (using numeric ID) — 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 details (using 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 with category breakdowns, methodology, narrative curl -X GET "https://api.tyrereviews.com/v1/tyres/3672/score-explanation" \ -H "X-API-Key: your_api_key_here" # Get tyre test results (works with both ID and pattern) curl -X GET "https://api.tyrereviews.com/v1/tyres/6/tests" \ -H "X-API-Key: your_api_key_here"
// Using Fetch API const API_KEY = 'your_api_key_here'; const BASE_URL = 'https://api.tyrereviews.com/v1'; const headers = { 'X-API-Key': API_KEY }; // Search for tyres async function searchTyres(pattern, season) { const res = await fetch( `${BASE_URL}/tyres/search?pattern=${pattern}&season=${season}`, { headers } ); return res.json(); } // Get tyre details (includes score_details with category breakdowns) async function getTyreDetails(tyreId) { const res = await fetch(`${BASE_URL}/tyres/${tyreId}`, { headers }); return res.json(); } // Get full score explanation async function getScoreExplanation(tyreId) { const res = await fetch( `${BASE_URL}/tyres/${tyreId}/score-explanation`, { headers } ); return res.json(); } // Usage: display category scores getTyreDetails(3672).then(({ data }) => { if (data.score_details) { // Primary categories (Wet, Dry, Snow, etc.) data.score_details.categories.forEach(cat => { console.log(`${cat.name}: ${cat.display_score}% (${cat.test_count} tests)`); }); // Derived categories (Braking, Handling, Traction) data.score_details.derived_categories.forEach(cat => { console.log(`${cat.name}: ${cat.display_score}%`); }); } }); // Usage: render full explanation modal getScoreExplanation(3672).then(({ data }) => { console.log(`Score: ${data.score.value}/10 (${data.score.confidence_tier})`); console.log(`Strengths: ${data.strengths.map(s => s.category).join(', ')}`); console.log(`Weaknesses: ${data.weaknesses.map(w => w.category).join(', ')}`); });
import requests API_KEY = 'your_api_key_here' BASE_URL = 'https://api.tyrereviews.com/v1' headers = {'X-API-Key': API_KEY} # Search for tyres 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() # Get tyre details (includes score_details with category breakdowns) def get_tyre_details(tyre_id): return requests.get(f'{BASE_URL}/tyres/{tyre_id}', headers=headers).json() # Get full score explanation def get_score_explanation(tyre_id): return requests.get(f'{BASE_URL}/tyres/{tyre_id}/score-explanation', headers=headers).json() # Usage: search and display scores results = search_tyres('continental', season=1, min_score=7.0) for tyre in results['data']: print(f"{tyre['full_name']} - Score: {tyre['score']}") # Usage: display category breakdowns tyre = get_tyre_details(3672) details = tyre['data'].get('score_details') if details: print("\nPrimary categories:") for cat in details['categories']: print(f" {cat['name']}: {cat['display_score']}% ({cat['test_count']} tests)") print("\nDerived categories:") for cat in details['derived_categories']: print(f" {cat['name']}: {cat['display_score']}%") # Usage: mileage estimate mileage = tyre['data'].get('expected_mileage') if mileage and mileage['has_data']: print(f"\nExpected mileage: {mileage['combined_mileage_miles']} miles " f"({mileage['confidence']} confidence)") # Usage: full score explanation explanation = get_score_explanation(3672) data = explanation['data'] print(f"\n{data['tyre']['full_name']}: {data['score']['value']}/10") print(f"Strengths: {', '.join(s['category'] for s in data['strengths'])}") print(f"Narrative: {data['narrative_explanation']}")
<?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); } // Search for tyres $results = apiRequest('/tyres/search', ['pattern' => 'michelin', 'season' => 1]); echo "Found " . $results['meta']['total'] . " tyres\n"; foreach ($results['data'] as $tyre) { echo $tyre['full_name'] . " - Score: " . $tyre['score'] . "\n"; } // Get tyre details with category breakdowns $tyre = apiRequest('/tyres/3672'); $data = $tyre['data']; echo $data['brand_name'] . " " . $data['title'] . "\n"; if ($data['score_details']) { echo "\nCategory Scores:\n"; foreach ($data['score_details']['categories'] as $cat) { echo " {$cat['name']}: {$cat['display_score']}% ({$cat['test_count']} tests)\n"; } echo "\nDerived Scores:\n"; foreach ($data['score_details']['derived_categories'] as $cat) { echo " {$cat['name']}: {$cat['display_score']}%\n"; } } // Get full score explanation $explanation = apiRequest('/tyres/3672/score-explanation'); $score = $explanation['data']; echo "\nScore: {$score['score']['value']}/10 ({$score['score']['confidence_tier']} confidence)\n"; echo "Narrative: {$score['narrative_explanation']}\n";

Error Handling

The API uses standard HTTP status codes to indicate success or failure:

Common Errors & Solutions
  • Empty search results? Check spelling (e.g., "Pirelli" not "Prelli")
  • 404 on /tyres/{pattern}? Pattern not found in tyre_alternative table - try searching first or use numeric ID
  • 401 Unauthorized? Check your API key in the X-API-Key header
Status Code Meaning Description
200 OK Request successful
400 Bad Request Invalid parameters or malformed request
401 Unauthorized Invalid or missing API key
404 Not Found Resource not found
429 Too Many Requests Rate limit exceeded
500 Internal Server Error Server error - please contact support

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"
  }
}

Rate Limits

Rate limits are enforced based on your subscription plan:

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

Professional Plan
  • 1,000 requests/hour
  • 100,000 requests/month
  • All historical data

Enterprise Plan
  • 10,000+ requests/hour
  • Unlimited requests
  • All features included
  • Custom endpoints
  • SLA guarantee

Rate Limit Headers

Every API response includes headers showing your current rate limit status:

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

Filtering

  • Use field filtering to reduce payload size
  • Request only the data you need
  • Use pagination for large result sets
  • Apply filters at the API level

Performance

  • Implement proper timeout handling
  • Monitor your API usage
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.

Documentation

Comprehensive guides and API reference

View Docs
Email Support

Get help from our technical team

Contact Us
GitHub

Examples and SDK libraries

View Code
Enterprise Support

Enterprise customers have access to:

  • Priority email support with 24-hour SLA
  • Technical account manager
  • Custom integration assistance
  • Direct phone support

TyreReviews API v1.0 • www.tyrereviews.com • © 2026 TyreReviews. All rights reserved.