API reference
The complete reference for the read-only Data API. For what it is and how to get access, start with the Developer API overview. Every endpoint is a GET, returns JSON, and is versioned under /v1.
Base URL
https://api.retrotechcollector.app/developer/v1
Authentication
Every request needs an API key, created under Settings → Developer API. Keys look like rtc_live_…. Present the key either as a Bearer token or in an X-API-Key header — pick one:
# Bearer token
curl https://api.retrotechcollector.app/developer/v1/me \
-H "Authorization: Bearer rtc_live_your_key_here"
# or the X-API-Key header
curl https://api.retrotechcollector.app/developer/v1/me \
-H "X-API-Key: rtc_live_your_key_here"
The API is machine-to-machine and read-only: only GET, HEAD and OPTIONS are accepted, cookies are ignored, and there's no CORS for browser credentials.
Scopes
Each key carries a set of scopes, and every endpoint checks for the one it needs. A key missing the required scope gets 403 insufficient_scope.
| Scope | Grants | Endpoints |
|---|---|---|
catalogue:read | Public master-item metadata | /catalogue, /catalogue/:id |
prices:read | Market prices | /prices, /prices/:masterItemId |
export | Bulk CSV price export | /prices/export.csv |
collection:read | Your collection + value | /collection, /collection/value, /collection/:id |
marketplace:read | Your listings + offers | /listings, /offers |
transactions:read | Your transactions | /transactions |
Pagination
List endpoints accept limit (1–100, default 50) and offset (default 0), and wrap results in a data array with a pagination block:
{
"data": [],
"pagination": { "total": 1240, "limit": 50, "offset": 0, "hasMore": true }
}
Single-item endpoints return the object under data.
Rate limits and quota
Two limits apply, both enforced across servers:
- A per-minute burst limit — 120/min on Enthusiast, 60/min on the Developer API add-on. Over it returns
429 rate_limited. - A monthly quota — 50,000 on Enthusiast, 10,000 on the add-on. It resets at the start of each calendar month (UTC). Over it returns
429 quota_exceeded.
Metered responses include your quota headers:
X-RateLimit-Limit: 50000
X-RateLimit-Remaining: 49872
GET /v1/me is burst-limited but does not count against your monthly quota. A rejected request (a 400 or a scope 403) never burns quota either.
Account
GET /v1/me
Your plan, granted scopes, limits and current usage. No scope required.
curl https://api.retrotechcollector.app/developer/v1/me \
-H "Authorization: Bearer rtc_live_your_key_here"
{
"plan": "enthusiast",
"scopes": ["catalogue:read", "prices:read", "collection:read"],
"limits": { "monthly": 50000, "perMinute": 120 },
"usage": { "period": "2026-07", "used": 128, "remaining": 49872 },
"availableScopes": [
"catalogue:read", "prices:read", "collection:read",
"marketplace:read", "transactions:read", "export"
]
}
plan is either "enthusiast" or "addon".
Catalogue
Public master-item metadata for PUBLISHED items only. Supports search, platform, category and upc filters alongside limit and offset.
GET /v1/catalogue
Scope: catalogue:read.
curl "https://api.retrotechcollector.app/developer/v1/catalogue?platform=Nintendo%2064&limit=1" \
-H "Authorization: Bearer rtc_live_your_key_here"
{
"data": [
{
"masterItemId": 4821,
"name": "The Legend of Zelda: Ocarina of Time",
"slug": "the-legend-of-zelda-ocarina-of-time",
"category": "Game",
"platform": "Nintendo 64",
"subCategory": null,
"modelNumber": null,
"releaseYear": 1998,
"region": "PAL",
"format": "Cartridge",
"developer": "Nintendo EAD",
"publisher": "Nintendo",
"genre": "Action-adventure",
"manufacturer": "Nintendo",
"description": "An action-adventure game for the Nintendo 64.",
"imageUrl": "https://storage.googleapis.com/rtc-collector-images/images/master/oot.webp"
}
],
"pagination": { "total": 512, "limit": 1, "offset": 0, "hasMore": true }
}
GET /v1/catalogue/:id
Scope: catalogue:read. A single catalogue item by its master-item id. Returns 404 not_found if there's no PUBLISHED item with that id.
curl https://api.retrotechcollector.app/developer/v1/catalogue/4821 \
-H "Authorization: Bearer rtc_live_your_key_here"
{ "data": { "masterItemId": 4821, "name": "The Legend of Zelda: Ocarina of Time", "platform": "Nintendo 64", "category": "Game" } }
Prices
Market prices from PriceCharting, by condition. Prices carry a null where no value is known. Supports the same search, platform and upc filters plus limit and offset.
GET /v1/prices
Scope: prices:read.
curl "https://api.retrotechcollector.app/developer/v1/prices?search=ocarina&limit=1" \
-H "Authorization: Bearer rtc_live_your_key_here"
{
"data": [
{
"masterItemId": 4821,
"name": "The Legend of Zelda: Ocarina of Time",
"slug": "the-legend-of-zelda-ocarina-of-time",
"platform": "Nintendo 64",
"category": "Game",
"upc": "045496870027",
"loose": 32.5,
"cib": 74.99,
"new": 320.0,
"boxOnly": 25.0,
"manualOnly": 12.0,
"scrapeDate": "2026-07-05T03:00:00.000Z"
}
],
"pagination": { "total": 3, "limit": 1, "offset": 0, "hasMore": true }
}
Condition points: loose, cib, new, plus boxOnly and manualOnly for games.
GET /v1/prices/:masterItemId
Scope: prices:read. Prices for one master item. Returns 404 not_found if there's no match.
curl https://api.retrotechcollector.app/developer/v1/prices/4821 \
-H "Authorization: Bearer rtc_live_your_key_here"
{ "data": { "masterItemId": 4821, "name": "The Legend of Zelda: Ocarina of Time", "loose": 32.5, "cib": 74.99, "new": 320.0 } }
GET /v1/prices/export.csv
Scope: export. The same price rows as /v1/prices, streamed as an RFC 4180 CSV file (text/csv) with the columns masterItemId, name, slug, platform, category, upc, loose, cib, new, boxOnly, manualOnly, scrapeDate. Accepts the same filters.
curl "https://api.retrotechcollector.app/developer/v1/prices/export.csv?platform=Nintendo%2064" \
-H "Authorization: Bearer rtc_live_your_key_here" -o rtc-prices.csv
Your collection
Owner-scoped: every row is pinned to the account that owns the key. There's no way to pass another user's id.
GET /v1/collection
Scope: collection:read. Your collection items, paginated.
curl https://api.retrotechcollector.app/developer/v1/collection \
-H "Authorization: Bearer rtc_live_your_key_here"
{
"data": [
{
"id": 10233,
"masterItemId": 4821,
"name": "The Legend of Zelda: Ocarina of Time",
"category": "Game",
"condition": "CIB",
"status": "OWNED",
"platform": "Nintendo 64",
"releaseYear": 1998,
"estimatedValue": 74.99,
"purchasePrice": 45.0,
"acquiredAt": "2024-11-02T00:00:00.000Z",
"location": "Shelf B",
"isFavorite": true,
"createdAt": "2024-11-02T18:14:00.000Z",
"updatedAt": "2026-06-30T09:05:00.000Z"
}
],
"pagination": { "total": 142, "limit": 50, "offset": 0, "hasMore": true }
}
GET /v1/collection/value
Scope: collection:read. Aggregate value of your owned items.
curl https://api.retrotechcollector.app/developer/v1/collection/value \
-H "Authorization: Bearer rtc_live_your_key_here"
{ "data": { "ownedItems": 142, "estimatedValue": 8630.5 } }
GET /v1/collection/:id
Scope: collection:read. One of your collection items by id. Returns 404 not_found if it isn't yours or doesn't exist.
curl https://api.retrotechcollector.app/developer/v1/collection/10233 \
-H "Authorization: Bearer rtc_live_your_key_here"
{ "data": { "id": 10233, "masterItemId": 4821, "name": "The Legend of Zelda: Ocarina of Time", "condition": "CIB", "estimatedValue": 74.99 } }
Your marketplace activity
GET /v1/listings
Scope: marketplace:read. Your marketplace listings, paginated.
curl https://api.retrotechcollector.app/developer/v1/listings \
-H "Authorization: Bearer rtc_live_your_key_here"
{
"data": [
{
"id": 512,
"publicToken": "pub_a1b2c3d4",
"masterItemId": 4821,
"title": "Ocarina of Time — CIB, PAL",
"category": "Game",
"condition": "CIB",
"status": "ACTIVE",
"price": 79.99,
"currency": "GBP",
"acceptsTrade": true,
"shippingCost": 4.5,
"createdAt": "2026-06-20T10:00:00.000Z",
"updatedAt": "2026-07-01T12:30:00.000Z"
}
],
"pagination": { "total": 6, "limit": 50, "offset": 0, "hasMore": false }
}
GET /v1/offers
Scope: marketplace:read. Offers you've made, paginated.
curl https://api.retrotechcollector.app/developer/v1/offers \
-H "Authorization: Bearer rtc_live_your_key_here"
{
"data": [
{
"id": 88,
"listingId": 512,
"amount": 70.0,
"tradeItemId": null,
"message": "Would you take £70 posted?",
"status": "PENDING",
"createdAt": "2026-07-02T08:15:00.000Z",
"updatedAt": "2026-07-02T08:15:00.000Z"
}
],
"pagination": { "total": 3, "limit": 50, "offset": 0, "hasMore": false }
}
Your transactions
GET /v1/transactions
Scope: transactions:read. Transactions where you're the buyer or the seller, with a role telling you which. The counterparty's identity is never exposed.
curl https://api.retrotechcollector.app/developer/v1/transactions \
-H "Authorization: Bearer rtc_live_your_key_here"
{
"data": [
{
"id": 301,
"listingId": 512,
"amount": 79.99,
"platformFee": 2.0,
"status": "SHIPPED",
"trackingNumber": "JD0002123456",
"shippingCarrier": "Royal Mail",
"estimatedDelivery": "2026-07-09T00:00:00.000Z",
"actualDelivery": null,
"createdAt": "2026-07-03T14:00:00.000Z",
"updatedAt": "2026-07-04T09:20:00.000Z",
"role": "seller"
}
],
"pagination": { "total": 24, "limit": 50, "offset": 0, "hasMore": false }
}
Errors
Errors return a JSON body with an error code and, usually, a message:
{ "error": "insufficient_scope", "message": "This key is missing the 'prices:read' scope." }
| Status | error | When |
|---|---|---|
| 400 | bad_request | Invalid query or path parameter |
| 401 | unauthorized | Missing, invalid, revoked or expired key |
| 403 | forbidden | Developer API access isn't active on the account |
| 403 | insufficient_scope | The key lacks the scope the endpoint needs |
| 404 | not_found | No such item, or the route doesn't exist |
| 429 | rate_limited | Per-minute burst limit exceeded |
| 429 | quota_exceeded | Monthly quota reached |
| 503 | service_unavailable | Usage metering temporarily unavailable — retry shortly |
| 500 | server_error | Unexpected error |
A 403 forbidden means access has lapsed — check your plan. A 403 insufficient_scope means the key is fine but needs another scope; edit it under Settings → Developer API.