Skip to content
Scrappa Get API key
Edmunds API 1 credit/request

Edmunds Customer Reviews API Documentation

GET https://scrappa.co/api/edmunds/reviews/customer?submodel_id=200408605&page=1&per_page=2

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.

Edmunds Customer Reviews API Documentation 1 credit/request

Endpoint

Request preview
GET
https://scrappa.co/api/edmunds/reviews/customer?submodel_id=200408605&page=1&per_page=2
Auth header
x-api-key
Cost
1 credit/request
submodel_id = 200408605
Response preview
200 OK
{
    "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",
...

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.

submodel_id integer Required

Numeric submodel id from the submodels endpoint. Example: 200408605.

Example value 200408605
page integer Optional

Page number, starting at 1. Defaults to 1.

Example value 1
per_page integer Optional

Reviews per page, 1 to 50. Defaults to 20.

Example value 2
sort string Optional

most_helpful or newest. Defaults to most_helpful.

Example value relevance

Request Examples

PHP
<?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
<?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();
}
JavaScript
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));
JavaScript
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);
}
Ruby
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
Python
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()
Python
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}")
Java
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());
        }
    }
}
Go
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))
}
Terminal
#!/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"
C#
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}");
        }
    }
}
TypeScript
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();
RUST
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
JSON Response
200 OK
{
    "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.

422

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

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

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

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.