For business
Data API documentation
Everything you need to call the GCC Car Deals Data API: authentication, the endpoints with their parameters and responses, errors and limits.
Quick start
Subscribe to get an API key, keep it in an environment variable and send it as a Bearer token. This request asks for the market value of a Toyota Camry today.
Base URL: https://gcccardeals.com/api/b2b/v1
curl -s "https://gcccardeals.com/api/b2b/v1/valuation?make=Toyota&model=Camry&year=2019&km=90000" \
-H "Authorization: Bearer $GCC_API_KEY"Authentication
Send your API key in the Authorization header as a Bearer token, or in the X-API-Key header. Never put it in a URL: URLs are logged. Keys are confidential and issued per market, so a key for one market cannot query another. Starter includes a key for the market you choose; Pro and Business include a key for each market. You create your keys in your Data API dashboard, and the full key is shown only once.
Valuation
Available on every planGET https://gcccardeals.com/api/b2b/v1/valuation
The market value of one car on a date, with the comparable ads behind it.
Parameters
| Parameter | Required | Description |
|---|---|---|
make | Yes | The make as you would write it, for example Toyota. Names and common spellings are recognised. |
model | Yes | The model, for example Camry. |
year | Yes | The model year, from 1950 to next year. |
trim | No | The trim as written on the car, for example GXR. It narrows the comparison and never changes the car. |
km | No | The odometer reading in kilometres. When given, the value leans on cars with a similar mileage. |
as_of | No | The date to value the car on, as YYYY-MM-DD in UTC. Defaults to today. It must fall between the start of the market's price history and today, and within your plan's history window. |
condition | No | used (the default) or new. |
window_days | No | How many days back to look for comparable cars, counted from the valuation date (from today for the price table), from 30 to 180. Default 90. |
comparables | No | How many comparable ads to return as evidence, from 0 to 25. Default 10. |
market | No | Optional. It must match the market of your key; a mismatch is an error. |
Example request
curl -s "https://gcccardeals.com/api/b2b/v1/valuation?make=Toyota&model=Camry&year=2019&km=90000" \
-H "Authorization: Bearer $GCC_API_KEY"Example response
Illustrative values, shown to explain the format. They are not current prices, and the ad is an example.
{
"version": 1,
"method": "comparable-median-v1",
"market": "sa",
"currency": "SAR",
"as_of": "2026-09-15",
"window_days": 90,
"history_since": "2026-06-14",
"subject": {
"make": "toyota",
"model": "camry",
"model_year": 2019,
"trim": null,
"trim_label": null,
"km": 90000,
"condition": "used"
},
"valuation": {
"value": 52000,
"low": 47500,
"high": 56000,
"confidence": "high",
"basis": "model_year",
"premium_trim_group": null,
"mileage_matched": true
},
"counts": {
"candidates_total": 31,
"truncated": false,
"candidates": 31,
"distinct_cars": 27,
"outliers_dropped": 1,
"pool": 26,
"used": 13,
"same_trim": 0
},
"year_counts": {
"2019": 26
},
"pool": {
"median_price": 53000,
"p25": 48000,
"p75": 57000,
"median_km": 96000,
"sources": 4
},
"comparables": [
{
"source": "Example marketplace",
"url": "https://www.example.com/listing/12345",
"model_year": 2019,
"trim": null,
"km": 88000,
"asking_price": 51500,
"price_date": "2026-09-10",
"first_seen": "2026-08-30",
"last_seen": "2026-09-16",
"still_listed": true,
"listed_on_as_of": true,
"city": "riyadh"
}
],
"reason": null,
"quota": {
"monthly": 3000,
"used_month": 12,
"daily": null,
"used_today": null
},
"notes": [
"Prices are asking prices from the listings we observe, not transaction prices."
]
}Response fields
version- The response format version. Within a version, fields are added and never removed or renamed.
method- The name and version of the method that produced the answer.
market- The market the answer is for: qa, ae or sa.
currency- The currency of every price in the answer.
as_of- The date the answer is for, as a UTC date.
window_days- How many days back from as_of the comparable cars were taken from.
history_since- The first date this market has price history for.
subject- The car as we understood it: make, model, model_year, trim, trim_label, km and condition.
valuation.value- The market value: the typical asking price of the comparable cars. Null when there are too few comparable cars; reason says why.
valuation.low- The lower end of the range in which the middle half of comparable asking prices fall.
valuation.high- The upper end of that range.
valuation.confidence- How much evidence stands behind the value: high, medium or low.
valuation.basis- What the car was compared against: its trim, its trim group, its model year or a band of neighbouring model years.
valuation.premium_trim_group- The price-moving trim group the car was valued against, when its trim belongs to one.
valuation.mileage_matched- True when the value leans on cars with a mileage close to yours.
counts.candidates_total- All matching ads we observed in the window.
counts.truncated- True when candidates_total is larger than the number of ads read.
counts.candidates- The ads read for this valuation.
counts.distinct_cars- The number of separate cars behind those ads; a car advertised more than once counts once.
counts.outliers_dropped- Cars set aside because their price is unusual for this comparison.
counts.pool- The cars left in the comparison after that.
counts.used- The cars the value was taken from.
counts.same_trim- How many of the cars used share the trim you gave.
year_counts- How many comparable cars there are per model year, which shows which way a band of years leans.
pool.median_price- The median asking price across the whole comparison set.
pool.p25- The lower end of the middle half of that set's asking prices.
pool.p75- The upper end of the middle half of that set's asking prices.
pool.median_km- The median mileage of the set, in kilometres.
pool.sources- How many marketplaces the set comes from.
comparables[].source- The marketplace the ad was found on.
comparables[].url- A link to the original ad.
comparables[].model_year- The ad's model year.
comparables[].trim- The ad's trim, when it states one.
comparables[].km- The ad's odometer reading in kilometres, when it states one.
comparables[].asking_price- The ad's asking price on price_date, in the market's currency.
comparables[].price_date- The date of the asking price used.
comparables[].first_seen- The date we first saw the ad.
comparables[].last_seen- The date we last saw the ad.
comparables[].still_listed- Whether the ad is still listed today.
comparables[].listed_on_as_of- Whether the ad was listed on the as_of date itself.
comparables[].city- The city the ad gives, when it gives one.
reason- When no value could be given, a plain-language reason. Otherwise null.
quota- Your quota and how much of it you have used: monthly, used_month, daily and used_today.
notes- Plain-language notes on how to read the numbers.
Market prices
Available on every planGET https://gcccardeals.com/api/b2b/v1/market-prices
The typical asking price and its range for one make and model, by model year, trim family and mileage band.
Parameters
| Parameter | Required | Description |
|---|---|---|
make | Yes | The make as you would write it, for example Toyota. Names and common spellings are recognised. |
model | Yes | The model, for example Camry. |
condition | No | used (the default) or new. |
window_days | No | How many days back to look for comparable cars, counted from the valuation date (from today for the price table), from 30 to 180. Default 90. |
market | No | Optional. It must match the market of your key; a mismatch is an error. |
Example request
curl -s "https://gcccardeals.com/api/b2b/v1/market-prices?make=Toyota&model=Camry" \
-H "Authorization: Bearer $GCC_API_KEY"Example response
Illustrative values, shown to explain the format. They are not current prices, and the ad is an example.
{
"version": 1,
"method": "market-prices-v1",
"market": "sa",
"currency": "SAR",
"as_of": "2026-09-29",
"window_days": 90,
"history_since": "2026-06-14",
"make": "toyota",
"model": "camry",
"condition": "used",
"cells": [
{
"model_year": 2019,
"trim_family": null,
"mileage_band": "100-150k",
"cars": 12,
"median_price": 52000,
"p25_price": 48000,
"p75_price": 56000,
"median_km": 128000
}
],
"quota": {
"monthly": 3000,
"used_month": 12,
"daily": null,
"used_today": null
},
"notes": [
"Prices are asking prices from the listings we observe, not transaction prices."
]
}Response fields
version- The response format version. Within a version, fields are added and never removed or renamed.
method- The name and version of the method that produced the answer.
market- The market the answer is for: qa, ae or sa.
currency- The currency of every price in the answer.
as_of- The date the answer is for, as a UTC date.
window_days- How many days back from as_of the comparable cars were taken from.
history_since- The first date this market has price history for.
make- The make as we list it.
model- The model as we list it.
condition- used or new.
cells- The price table for this make and model: one entry per model year, trim family and mileage band.
cells[].model_year- The model year.
cells[].trim_family- The trim family, or null for the base trims.
cells[].mileage_band- The mileage band the cars fall in.
cells[].cars- The number of separate cars in the group.
cells[].median_price- The typical asking price of the group. Null for a group too small to price.
cells[].p25_price- The lower end of the middle half of asking prices, or null.
cells[].p75_price- The upper end of the middle half of asking prices, or null.
cells[].median_km- The median mileage of the group, in kilometres.
quota- Your quota and how much of it you have used: monthly, used_month, daily and used_today.
notes- Plain-language notes on how to read the numbers.
Full market table (CSV)
Pro and BusinessGET https://gcccardeals.com/api/b2b/v1/market-prices.csv
The whole market's price table as one CSV file, refreshed every day. A download counts as one call.
Parameters
| Parameter | Required | Description |
|---|---|---|
market | No | Optional. It must match the market of your key; a mismatch is an error. |
Example request
curl -s "https://gcccardeals.com/api/b2b/v1/market-prices.csv" \
-H "Authorization: Bearer $GCC_API_KEY" \
-o market-prices.csvThe file is streamed. If the connection breaks before the end, discard it: the X-Total-Rows header tells you how many rows to expect.
Columns
make- The make as we list it.
model- The model as we list it.
model_year- The model year.
trim_family- The trim family, or null for the base trims.
condition- used or new.
mileage_band- The mileage band the cars fall in.
cars- The number of separate cars in the group.
median_price- The typical asking price of the group. Null for a group too small to price.
p25_price- The lower end of the middle half of asking prices, or null.
p75_price- The upper end of the middle half of asking prices, or null.
median_km- The median mileage of the group, in kilometres.
currency- The currency of every price in the answer.
computed_on- The date the table was computed, as a UTC date.
Errors
A refusal returns the matching HTTP status and a JSON body with a code you can act on and a message a person can read.
| Status | Code | Meaning |
|---|---|---|
400 | bad_request | A parameter is missing or invalid. The message says which. No quota is used. |
401 | unauthorized | The key is missing, malformed, expired or revoked. |
403 | plan_limit | Your plan does not include this request, for example the full table on Starter or a date further back than your plan's history window. The message says what is missing. |
422 | unknown_vehicle | We do not recognise the make or model, and the answer lists some models we do know. A model we list that has no comparable cars in the window is not an error: the answer has no value and says why. |
429 | rate_limited | Too many requests in a short time. Wait the number of seconds in the Retry-After header. |
429 | busy | Another request with this key is still running. Send one request at a time. |
429 | quota_exceeded | Your monthly quota for this market is used up. It renews at the start of the next calendar month (UTC). |
503 | unavailable | The data could not be read right now. Retry after the number of seconds in the Retry-After header. It is never an answer about the car. |
Limits and quota headers
Each plan has a monthly quota of calls in every market it covers, counted from the start of the calendar month (UTC). A valuation, a market-price lookup and a full-table download each count as one call. Each client IP address can also send up to 120 requests a minute, and only one request per key can be in flight at a time.
A successful answer reports your quota in three headers. Two more are worth knowing.
| Header | Description |
|---|---|
X-RateLimit-Limit | Your quota for this market in the current period. |
X-RateLimit-Remaining | The calls left in the period after this one. |
X-RateLimit-Reset | When the quota renews, as a Unix timestamp in seconds (UTC). |
Retry-After | On a rate-limit or unavailable error: the seconds to wait before you retry. |
X-Total-Rows | On the CSV download: the number of data rows in the file, to check it arrived whole. |
Limits by plan
| Plan | Calls per market per month | Markets | Past-date valuations | Full daily price table (CSV) |
|---|---|---|---|---|
| Starter | 300 | One market of your choice | Last 90 days | Not included |
| Pro | 3,000 | All markets | Last 90 days | Included |
| Business | 15,000 | All markets | The whole history | Included |
Price history
Each market's price history starts on a fixed date. A valuation can be asked for any date (as_of) from that day, within the history window of your plan.
| Market | History since |
|---|---|
| Qatar | Jun 7, 2026 |
| UAE | Jun 12, 2026 |
| Saudi | Jun 14, 2026 |
Get an API key
Sign-up, payment and API keys are handled at dealers.gcccardeals.com: subscribe, then create a key for each market in your Data API dashboard.
Try the shape of the data before you subscribe: a free CSV of the price tables for Saudi Arabia.