Coverage is still narrow. Live prices have been read from 1 of 129 panels (2,182 services). The rest are listed because they are real, reachable operators — not because we have seen their rates. Panels with no synced catalogue show no prices rather than an estimate. How the data is gathered.
Market-wide totals and per-platform rollups — the numbers the site itself cites.
Revalidated every 30 minutes
What does every response look like?
One envelope for every endpoint: the payload under data, everything about the payload under _meta. Data lifted out of a response arrives somewhere else still carrying its licence and its source.
One exception worth knowing: on /api/v1/services/{platform}/{service} the offer list is capped by limit but not paged — offset is parsed and has no effect, and no pagination block is returned. Raise limit to 200 to see the full offer list for a service.
GET /api/v1/panels
The ranked panel list, with every filter the site itself uses. Panels with status flagged are excluded from this endpoint entirely. An unknown sort or feature value returns 400 with the valid values in the message, rather than silently ignoring it.
Query parameters for /api/v1/panels
Parameter
Type
Notes
sort
string
best (default), cheapest, trust, newest, services, uptime, rating. Anything else is a 400.
limit / offset
integer
Standard pagination. Default 50, maximum 200.
platform
string
Platform slug, e.g. instagram. Matches panels carrying at least one service for it.
payment
string
Payment method slug, e.g. crypto, upi, paypal.
country
string
ISO country code of the panel’s registered jurisdiction. Case-insensitive.
feature
string, repeatable
Capability slug. Repeat the parameter to require several: ?feature=api&feature=refill. Unknown values are a 400.
minTrust
number
Lower bound on the 0–100 trust score.
maxDeposit
number
Upper bound on minimum deposit. Accepted by the endpoint but omitted from the discovery document.
q
string
Substring match against panel name and domain.
Panel object fields
Field
Type
What it holds
slug
string
Stable identifier. This is the panel’s identity across every endpoint.
name
string
Display name.
domain
string
Bare hostname, no scheme.
website
string
https:// plus the domain. Never the monetised outbound URL.
url
string
Canonical PanelCompare page for the panel.
tagline / description
string | null
One-sentence and long-form summaries.
status
string
active, unverified, paused, offline or flagged.
launchedYear
number | null
Stated or evidenced launch year.
countryCode
string | null
Registered jurisdiction where the panel publishes one. Never inferred.
currency
string
The currency the panel prices in.
minDeposit
number | null
Smallest accepted deposit, in that currency.
isAffiliate / isClaimed / isSponsored
boolean
Monetisation and verification state, exposed rather than hidden.
One panel, with every field above plus an offerings array covering its whole active catalogue. Each offering carries marketMedianPer1000 and marketSampleSize beside the price, so a consumer can reproduce a “below market” verdict instead of taking one on trust. _meta.offeringCount gives the array length. An unknown slug returns 404 with code panel_not_found.
The canonical taxonomy. Every panel’s raw service names are mapped onto these rows, which is what makes cross-panel comparison possible at all — so this is the endpoint to read before any other. Each row carries a reference price band and the typical order bounds for the service. An unknown platform returns 404 with code platform_not_found.
Query parameters for /api/v1/services
Parameter
Type
Notes
platform
string
Platform slug. Omit for the full taxonomy across all platforms.
limit / offset
integer
Standard pagination, applied after the platform filter.
The price table for one service: the canonical row, the current index figures, up to 90 days of index history, and every panel selling it ordered cheapest first. This is the endpoint behind the comparison tables on the site. An unknown path returns 404 with code service_not_found.
Query parameters for a single service
Parameter
Type
Notes
limit
integer
Caps the offers array. Default 50, maximum 200.
minTrust
number
Excludes offers from panels below this trust score, which is how you get a shortlist rather than a price floor.
offset
integer
Parsed but not applied on this endpoint; the offers array is capped rather than paged.
Offer object fields
Field
Type
What it holds
panel
object
slug, name, url, trustScore, overallScore.
pricePer1000
number
Rate per 1,000 units in the offer’s currency.
currency
string
Currency of this offer.
minOrder / maxOrder
number | null
Order quantity bounds.
quality
string
bot, mixed, real, hq-real, targeted or unknown.
refillDays
number
Refill window in days. 0 is none, 9999 is lifetime.
dripFeed / cancellable
boolean
Per-offer, not per-panel — panels support these unevenly across their catalogue.
startTimeMinutes / speedPerDay
number | null
Delivery claims as the panel states them.
source
string
api, manual or import — how the row entered the index.
lastSeenAt
string
ISO 8601 timestamp of the last sync that saw this row.
The daily aggregate, one row per service, in exactly the shape the bulk CSV and JSON downloads publish. One dataset, three transports — a reader who diffs them finds nothing. _meta.day carries the aggregate date and _meta.bulk the paths to the whole-file downloads, which are the right choice for anything larger than a page.
Price index row fields
Field
Type
What it holds
platform_slug / platform
string
Platform identifier and display name.
service_slug / service
string
Canonical service identifier and display name.
unit
string
The noun one unit counts: followers, views, hours.
day
string
YYYY-MM-DD the aggregate was computed for.
currency
string
Always USD in this dataset.
min_price_per_1000
number
Lowest active offer that day.
p25_price_per_1000
number
25th percentile.
median_price_per_1000
number
Median — the figure to quote if you quote one.
p75_price_per_1000
number
75th percentile.
max_price_per_1000
number
Highest active offer that day.
panels_sampled
number
Panels in the sample. Below about 5 the median is noise.
Market-wide totals and a per-platform rollup: services, offerings, panels selling and the cheapest rate for each platform. These are the figures rendered on the market statistics page, read from the same queries. One naming note worth reading before you quote it: prices.meanOfServiceMediansPer1000 is the mean of every service’s median, not a basket price and not the market median.
Errors drop the envelope entirely and return an error object with a stable machine code. They are sent with Cache-Control: no-store, so a fixed request is not served a stale failure.
The sort parameter is not one of the seven accepted values. The message lists them.
invalid_feature
400
A feature parameter is not a known capability slug. The message lists every valid slug.
panel_not_found
404
No panel with that slug.
platform_not_found
404
No platform with that slug on /api/v1/services.
service_not_found
404
No service at that platform/service path.
What are the rate limits and caching rules?
Stated plainly, including where the answer is “nothing yet”.
Rate limits, caching and response headers
Policy
Current value
Authentication
None. No key, no account, no signup.
Rate limit
None enforced. No quota headers are returned, because there is no quota to report. Prefer the bulk downloads for whole-dataset work, and if a limit ever becomes necessary it will be documented here before it is enforced.
Methods
GET and OPTIONS. There is no write surface.
CORS
Access-Control-Allow-Origin: * on every endpoint, so browser clients need no proxy.
Caching
public, s-maxage=600, stale-while-revalidate=3600. Shared caches hold a response for ten minutes and may serve it stale for an hour while refreshing.
Content type
application/json; charset=utf-8, pretty-printed with two-space indentation.
Indexing
Responses carry X-Robots-Tag: noindex, and /api/ is disallowed in robots.txt. Neither affects a script or an agent fetching the endpoint directly.
What are you allowed to do with the data?
Published under Creative Commons Attribution 4.0 International. Commercial use, redistribution and derivative works are all permitted.
The one condition is attribution. Credit PanelCompare and link back to the source. Every response hands you the exact string to use in _meta.attribution, so nothing has to be composed by hand.
Attribution, in text
Data: PanelCompare (https://panelcompare.com), CC BY 4.0. Retrieved Sep 7, 2026.
Attribution, in HTML
<p>Data: <a href="https://panelcompare.com" rel="noopener">PanelCompare</a>,
<a href="https://creativecommons.org/licenses/by/4.0/">CC BY 4.0</a>.</p>
If you republish figures at scale, carry the observation date with them. A price in this market is a measurement of one day, and a rate quoted without its date is a claim rather than a fact — which is the failure mode this whole dataset exists to fix.
Is there a bulk download?
Yes, and it is the right choice for anything larger than a page of results. Same rows, same column names, same licence.
CSV column names are part of the same contract as the JSON field names: columns get added, never renamed or reordered, because renaming one silently breaks every notebook built on the file.
What is not in the API?
Stated so nobody builds against something that does not exist.
No write endpoints. Reviews, panel submissions and reports go through the site, not the API.
No reviews endpoint. Panel objects expose an aggregate rating, but individual review text is not served over the API.
No uptime history. Panels expose reliability.uptimePct30d as a rolling figure; the underlying probe log is not exposed.
No webhooks and no push. Poll on the cache window, or take the daily bulk file.
No historical panel scores. Price history is available per service through the index history; score history is not.
API: common questions
Do I need an API key?
No. There is no key, no registration and no account. Every endpoint is a public GET with CORS open to all origins, so it works from a browser, a notebook or a server with nothing configured. The only condition on using the data is attribution under CC BY 4.0.
What is the rate limit?
None is enforced today. Responses carry a ten-minute shared-cache directive, so a well-behaved client hitting a CDN-fronted deployment mostly reads cache rather than the database. If a client ever causes a problem we will add limits and document them on this page before enforcing them, rather than discovering them by being blocked.
Why does robots.txt disallow /api/?
Because a crawler spending its budget on JSON is a crawler not reading the pages that explain what the JSON means. The disallow is a crawl-efficiency measure aimed at bots, and it has no effect on you: a browser, a script or an agent fetching the endpoint directly is unaffected, and this documentation page is fully indexable so the API stays discoverable.
Can I use this data commercially?
Yes. CC BY 4.0 permits commercial use, redistribution and derivative works, including inside a paid product. The single requirement is attribution: credit PanelCompare and link to the source. If you republish figures at scale, please also carry the observation date — a price from this market is meaningless without one.
How current is the data?
Prices and catalogues refresh on a thirty-minute window, panel scores and capability flags on a six-hour window, and the price index is a daily aggregate. Every response carries _meta.generatedAt, and most objects carry their own updatedAt or lastSeenAt, so a consumer never has to guess how stale a figure is.
What happens if a field changes?
Field names are treated as a contract from the first consumer onward. Fields get added freely; renaming or removing one happens behind a /api/v2 rather than in place. The same rule governs the CSV column names in the bulk download.
Related
The same data, rendered for people rather than for machines.