Get the owner reviews of one submodel and model year: average rating, review count and for each review the author name, title, text, overall rating, topic ratings, helpful votes, style, odometer reading and dates (ISO 8601, UTC). Sort by most helpful or newest. An unknown submodel id returns a not-billable 404.
Run this endpoint
Endpoint
Parameters
Start with the required fields, then add optional filters only when your use case needs them.
Runnable path
1 required parameter needed before sending a request.
3 optional filters available.
integer
Required
Numeric submodel id from the submodels endpoint. Example: 200408605.
200408605
integer
Optional
Page number, starting at 1. Defaults to 1.
1
integer
Optional
Reviews per page, 1 to 50. Defaults to 20.
2
string
Optional
most_helpful or newest. Defaults to most_helpful.
relevance
Request Examples
<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://scrappa.co/api/edmunds/reviews/customer?submodel_id=200408605&page=1&per_page=2",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "GET",
CURLOPT_HTTPHEADER => [
"x-api-key: YOUR_API_KEY_HERE"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}
<?php
use Illuminate\Support\Facades\Http;
$response = Http::timeout(30)
->withHeaders(['x-api-key' => 'YOUR_API_KEY_HERE'])
->get('https://scrappa.co/api/edmunds/reviews/customer?submodel_id=200408605&page=1&per_page=2');
if ($response->successful()) {
echo $response->body();
} else {
echo "Error: " . $response->status();
}
const options = {
method: 'GET',
headers: {
'x-api-key': 'YOUR_API_KEY_HERE'
}
};
fetch('https://scrappa.co/api/edmunds/reviews/customer?submodel_id=200408605&page=1&per_page=2', options)
.then(response => {
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}
return response.text();
})
.then(data => console.log(data))
.catch(error => console.error('Error:', error));
const axios = require('axios');
const options = {
method: 'GET',
url: 'https://scrappa.co/api/edmunds/reviews/customer?submodel_id=200408605&page=1&per_page=2',
headers: {
x-api-key: 'YOUR_API_KEY_HERE',
}
};
try {
const response = await axios(options);
console.log(response.data);
} catch (error) {
console.error('Error:', error.message);
}
require 'net/http'
require 'uri'
uri = URI.parse("https://scrappa.co/api/edmunds/reviews/customer?submodel_id=200408605&page=1&per_page=2")
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = uri.scheme == 'https'
request = Net::HTTP::Get.new(uri.request_uri)
request['x-api-key'] = 'YOUR_API_KEY_HERE'
begin
response = http.request(request)
puts response.body
rescue => e
puts "Error: #{e.message}"
end
import http.client
import json
conn = http.client.HTTPSConnection("scrappa.co")
headers = {
'x-api-key': 'YOUR_API_KEY_HERE',
}
try:
conn.request("GET", "/api/edmunds/reviews/customer?submodel_id=200408605&page=1&per_page=2", headers=headers)
res = conn.getresponse()
data = res.read()
print(data.decode("utf-8"))
except Exception as e:
print(f"Error: {e}")
finally:
conn.close()
import requests
headers = {
'x-api-key': 'YOUR_API_KEY_HERE',
}
try:
response = requests.get('https://scrappa.co/api/edmunds/reviews/customer?submodel_id=200408605&page=1&per_page=2', headers=headers)
response.raise_for_status()
print(response.text)
except requests.exceptions.RequestException as e:
print(f"Error: {e}")
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
import java.io.IOException;
public class ApiExample {
public static void main(String[] args) {
OkHttpClient client = new OkHttpClient();
Request request = new Request.Builder()
.url("https://scrappa.co/api/edmunds/reviews/customer?submodel_id=200408605&page=1&per_page=2")
.addHeader("x-api-key", "YOUR_API_KEY_HERE")
.build();
try (Response response = client.newCall(request).execute()) {
if (response.isSuccessful()) {
System.out.println(response.body().string());
} else {
System.out.println("Error: " + response.code());
}
} catch (IOException e) {
System.out.println("Error: " + e.getMessage());
}
}
}
package main
import (
"fmt"
"net/http"
"io/ioutil"
)
func main() {
client := &http.Client{}
req, err := http.NewRequest("GET", "https://scrappa.co/api/edmunds/reviews/customer?submodel_id=200408605&page=1&per_page=2", nil)
if err != nil {
fmt.Println("Error creating request:", err)
return
}
req.Header.Set("x-api-key", "YOUR_API_KEY_HERE")
resp, err := client.Do(req)
if err != nil {
fmt.Println("Error making request:", err)
return
}
defer resp.Body.Close()
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
fmt.Println("Error reading response:", err)
return
}
fmt.Println(string(body))
}
#!/bin/bash
curl -X GET \
-H "x-api-key: YOUR_API_KEY_HERE" \
"https://scrappa.co/api/edmunds/reviews/customer?submodel_id=200408605&page=1&per_page=2"
using System;
using System.Net.Http;
using System.Threading.Tasks;
class Program
{
static async Task Main()
{
using var client = new HttpClient();
client.DefaultRequestHeaders.Add("x-api-key", "YOUR_API_KEY_HERE");
try
{
var response = await client.SendAsync(new HttpRequestMessage(HttpMethod.Get, "https://scrappa.co/api/edmunds/reviews/customer?submodel_id=200408605&page=1&per_page=2"));
var content = await response.Content.ReadAsStringAsync();
Console.WriteLine(content);
}
catch (Exception ex)
{
Console.WriteLine($"Error: {ex.Message}");
}
}
}
import axios from 'axios';
async function run(): Promise<void> {
try {
const response = await axios({
method: 'GET',
url: 'https://scrappa.co/api/edmunds/reviews/customer?submodel_id=200408605&page=1&per_page=2',
headers: {
'x-api-key': 'YOUR_API_KEY_HERE',
},
});
console.log(response.data);
} catch (error) {
console.error('Error:', error);
}
}
void run();
use reqwest::Client;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let client = Client::new();
let response = client
.get("https://scrappa.co/api/edmunds/reviews/customer?submodel_id=200408605&page=1&per_page=2")
.header("x-api-key", "YOUR_API_KEY_HERE")
.send()
.await?;
println!("{}", response.text().await?);
Ok(())
}
Response Schema
Example response fields are illustrative; inspect the JSON before integrating.
Example response fields
Scan these fields before integrating.
success
data
meta
{
"success": true,
"data": {
"submodel_id": 200408605,
"average_rating": 3.92,
"reviews_count": 146,
"total_pages": 73,
"page": 1,
"per_page": 2,
"reviews": [
{
"id": "843273478517850112",
"author_name": "Detectivejojima",
"title": "Not Toyotas Finest Effort",
"text": "The car overall is a good car for everyday transportation. Quiet, comfortable and reliable. Not exciting, nor fun to drive, but it does the job. Weak points are struts, which had to be replaced around 40k. Small leaks and very soft, just too soft, and not under warranty. Needed to replace power booster on brakes around 150k. First time on any car I've owned. Those are expensive fixes. Also, now at 175k mileage, smoke comes out of exhaust when 1st starting in morning, regardless of weather. My mechanic says oil burn, but oil does not drop between oil changes, so not much oil burn, if that is what is causing smoke. But still runs great, no other major problems and I guess it's been overall a reliable Toyota, but below my other experiences with my 5 other Toyotas over the years.\n\nUpdate: 9/9/17 - I recently sold my Camry, 7/10/17, as it was starting to smoke more on start-up, and was verified by my mechanic as oil burn. It also started to consume oil, approximately a quart every 2-3000 miles. The extended warranty ran out in October of 2016, so no warranty either. This, a Toyota Camry, that basically lasted less than 200,000 with meticulous care on my part. Very frustrating, as I always believed most problems with cars start with owners, but this was a design issue with the engine, and Toyota refused to acknowledge it. From the struts failing at 40k, the water pump around 48-50k, the power brake booster failing at 150k, and many other smaller issues that I never encountered with in over 40 years of ownership of 5 other Toyota models. VERY DISAPPOINTED IN TOYOTA DEALER RESPONSE. OF COURSE TOYOTA COULD CARE LESS, AS THEY SELL 400,000 OF THESE A YEAR, BUT WHEN YOU MAINTAIN A CAR AS WELL AS I HAVE, AND IT'S A DESIGN ISSUE, YOU WOULD THINK THAT A MANUFACTURER WITH THE REPUTATION OF TOYOTA WOULD STEP UP AND DO WHAT IS THE RIGHT THING, EITHER REPAIR OR REPLACE. THAT IS WHY I AM BUYING A NEW HONDA TODAY, 9/9/17, AS OPPOSED TO THE NEW 2018 CAMRY.",
"rating": 3,
"ratings": {
"comfort": 4,
"interior": 4,
"performance": 3,
"reliability": 4,
"safety": 3,
"technology": 3,
"value": 4
},
"thumbs_up": 44,
"thumbs_down": 5,
"style_id": "100900018",
"style": "CE 4dr Sedan (2.4L 4cyl 5M)",
"odometer_miles": 198000,
"created_at": "2016-03-09T19:53:52Z",
"updated_at": "2017-09-11T14:30:26Z"
},
{
"id": "810907224452628480",
"author_name": "Hermania",
"title": "Buyer beware",
"text": "I bought my Camry new in 08. At 75,000 the engine blew. I took it to the dealer and they stated there is a design flaw in all Camrys in that they burn oil at a rate of 2 qts per 3000 miles. If you check your oil between changes you will discover this for yourself. It was in the dealership for 3 months and is still not running properly. Please take this advice and don't listen to the Toyota dealers. There is a serious design flaw in all Camrys. They are counting on you not checking the oil in between regular oil changes and before you realize it, blown engine. I was a big fan of the Toyota lines but now will not even consider buying one. I am not disgruntled by this experience , I just want to save others the headache of going thorough what I did. There are better choices out there. And by the way: all toyota service centers are crooked! Buyer beware.",
"rating": 1,
"ratings": {
"comfort": 2,
"interior": 2,
"performance": 1,
"reliability": 1,
"safety": 3,
"technology": 2,
"value": 1
},
"thumbs_up": 37,
"thumbs_down": 7,
"style_id": "100900018",
"style": "CE 4dr Sedan (2.4L 4cyl 5M)",
"odometer_miles": 75000,
"created_at": "2016-01-25T04:07:54Z",
"updated_at": "2016-02-02T19:07:15Z"
}
]
},
"meta": {
"endpoint_family": "customer_reviews",
"billable": true
}
}
Errors
Handle these documented responses before retrying or showing customer-facing failures.
Validation Error
A required query parameter is missing or invalid. This response is not billable.
{
"errors": {
"submodel_id": [
"The submodel_id field is required."
]
},
"message": "The request validation failed"
}Resource Not Found
The requested Edmunds resource does not exist. This response is not billable.
{
"meta": {
"billable": false,
"retryable": false,
"endpoint_family": "customer_reviews"
},
"error": {
"code": "NOT_FOUND",
"message": "The requested Edmunds resource was not found."
},
"success": false
}Invalid Source Response
The upstream answered with a shape that no longer matches the documented contract. This response is not billable.
{
"error": {
"code": "PARSER_DRIFT",
"message": "The Edmunds API is temporarily unavailable. Please retry."
},
"success": false
}Service Unavailable
The upstream service is temporarily unavailable. Please retry shortly.
{
"error": {
"code": "UPSTREAM_UNAVAILABLE",
"message": "The Edmunds API is temporarily unavailable. Please retry."
},
"success": false
}Generate Code with AI
Copy a ready-made prompt with all the endpoint details, parameters, and example responses. Paste it into ChatGPT, Claude, or any AI assistant to instantly generate working code.
Try It Live
Test this endpoint in our interactive playground with real data.