ALT/FNDATA Data API
Access 19M+ luxury auction records across watches, handbags, jewelry, gems, collector cars, motorcycles, aircraft, and wine & whisky from 100+ auction houses worldwide — including Christie's, Sotheby's, Phillips, Bonhams, RM Sotheby's, Barrett-Jackson, and more.
Base URL
Recommended path for new developers
Follow these steps to go from zero to a working integration.
Get your API key
You generate your API key in your account at app.altfndata.com. Set it in the X-API-Key header for all requests.
Make your first API call
Use the POST query endpoint to search across any of the 18 datasets with filters and sorting, from watches and handbags to fine art, design, wine and more.
Go to Querying Data →Explore the datasets
Browse available tables, understand the columns, and discover what data you can query.
See Available Tables →Build with the API
Endpoints
Health checks, table listing, schema inspection, and querying.
Filter Operators
11 operators: eq, like, in, gt, is_null, and more.
Code Examples
Ready-to-use examples in curl, Python, and JavaScript.
Available datasets
Access is granted per API key — your key may authorize a subset of these tables.
Watches
Luxury watch auction results from major houses worldwide.
Handbags
Designer handbag auction results.
Jewelry
Jewelry and gemstone auction results.
Gems
Loose gemstone auction results (diamonds, sapphires, rubies, emeralds).
Automobile
Collector car auction results (Ferrari, Porsche, Mercedes-Benz, and more).
Motorcycle
Collector motorcycle auction results (Harley-Davidson, Ducati, BMW).
Aircraft
Aircraft listings with airframe, engine, and cabin specifications.
Wine & Whisky
Wine and whisky auction results.
Fine Art
Fine art auction results across all movements and periods
Works of Art
Works of art with stone/jewelry relevance (jade, jadeite, diamond-set, etc.)
Design
Design and decorative arts — furniture, lighting (incl. Tiffany Studios lamps), glass, ceramics, and...
Books
Books, manuscripts, maps and printed material.
Coins
Numismatic coin auction results.
Automobilia
Automobilia — automotive memorabilia, parts, signage, models and related collectibles (not the cars themselves;...
Fashion
Fashion and couture — clothing and accessories (not handbags or shoes, which have their own tables).
Shoes
Footwear — designer shoes and collectible sneakers.
Other Automobile
Other vehicles -- non-car, non-motorcycle (boats, tractors, trucks, buses, military).
Perfume
Perfume and collectible fragrance bottles / flacons.
Accessories
Fashion accessories -- belts, scarves, cufflinks, brooches, sunglasses (incl. gem-set pieces).
Musical Instruments
Musical instruments -- guitars, violin family, pianos and keyboards, woodwind, brass, percussion, amplifiers.
Tools & Integrations
MCP Server for AI assistants
Query auction data in natural language from Claude, ChatGPT, Gemini, Perplexity or any other assistant or tool that supports MCP.
Swagger UI
Interactive API explorer with live request testing.
Authentication #
All endpoints except /v1/health require an API key. Pass your key in the X-API-Key header:
X-API-Key: afi_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
You generate your API key in your account at app.altfndata.com. Keep it secret — do not commit it to source control or share it publicly.
| Scenario | HTTP Status | Response |
|---|---|---|
| Key missing | 401 | {"detail": "Missing API key"} |
| Key invalid or inactive | 403 | {"detail": "Invalid API key"} |
| Key lacks table access | 403 | {"detail": "No access to table: watches"} |
Available Tables #
Eighteen datasets are available. Use the /v1/tables/{name}/schema endpoint to see all columns for any table. Access is granted per API key — your key may authorize a subset.
Publicly available fields
The columns listed below are the publicly available fields, and we update them frequently. For the current schema of any dataset, create an account at app.altfndata.com and open the Data Dictionary.
watches
Luxury watch auction results from major houses worldwide.
handbags
Designer handbag auction results.
jewelry
Jewelry and gemstone auction results.
gems
Loose gemstone auction results.
automobile
Collector car auction results.
motorcycle
Collector motorcycle auction results.
aircraft
Aircraft listings with airframe and engine specs.
wine_whisky
Wine and whisky auction results.
watches
| Column | Type | Description |
|---|---|---|
item_title | string | Watch description from the auction listing |
designer | string | Brand name (Rolex, Patek Philippe, Omega, etc.) |
manufacturer_name | string | Manufacturer (often same as designer) |
model | string | Model name (Submariner, Nautilus, etc.) |
vendor | string | Auction house (Phillips, Sotheby's, Christie's, etc.) |
sale_price | double | Hammer price in original sale currency |
sale_currency | string | Original currency (USD, GBP, EUR, CHF, etc.) |
usd_price_decimal | double | Price converted to USD |
sale_date | string | Auction date (YYYY-MM-DD) |
sale_location | string | Auction city |
sale_location_country | string | Country |
status | string | Lot status (sold, unsold, withdrawn, etc.) |
sale_estimates_low_usd_price | double | Low estimate in USD |
sale_estimates_high_usd_price | double | High estimate in USD |
case_material | string | Case material (steel, gold, platinum, etc.) |
case_diameter | string | Case diameter |
dial_color | string | Dial color |
movement | string | Movement type |
reference | string | Reference number |
item_image | string | Primary image URL |
lot_url | string | Original auction lot URL |
handbags
| Column | Type | Description |
|---|---|---|
item_title | string | Handbag description from listing |
brand_name_clean | string | Standardized brand name (Hermes, Chanel, Louis Vuitton, etc.) |
designer | string | Designer name |
model | string | Model name (Birkin, Kelly, Classic Flap, etc.) |
vendor | string | Auction house |
sale_price | double | Hammer price in original currency |
sale_currency | string | Original currency |
usd_price_decimal | double | Price converted to USD |
sale_date | string | Auction date |
sale_location | string | Auction city |
sale_location_country | string | Country |
status | string | Lot status |
sale_estimates_low_usd_price | double | Low estimate in USD |
sale_estimates_high_usd_price | double | High estimate in USD |
materials | string | Bag materials |
item_type | string | Bag type (Shoulder Bag, Clutch, Tote, etc.) |
item_image | string | Primary image URL |
lot_url | string | Original lot URL |
jewelry
| Column | Type | Description |
|---|---|---|
item_title | string | Jewelry description from listing |
designer | string | Designer or brand name |
manufacturer_name | string | Manufacturer |
vendor | string | Auction house |
sale_price | double | Hammer price in original currency |
sale_currency | string | Original currency |
usd_price_decimal | double | Price converted to USD |
sale_date | string | Auction date |
sale_location | string | Auction city |
sale_location_country | string | Country |
status | string | Lot status |
sale_estimates_low_usd_price | double | Low estimate in USD |
sale_estimates_high_usd_price | double | High estimate in USD |
gem_type | string | Gemstone type (Diamond, Ruby, Sapphire, Emerald, etc.) |
primary_gem | string | Primary gemstone |
carats | double | Carat weight |
gemstone_cut | string | Cut type |
gemstone_clarity | string | Clarity grade |
color | string | Gemstone color |
item_type | string | Jewelry type (Ring, Necklace, Bracelet, etc.) |
item_image | string | Primary image URL |
lot_url | string | Original lot URL |
gems
| Column | Type | Description |
|---|---|---|
item_title | string | Gemstone description from listing |
vendor | string | Auction house |
sale_price | double | Hammer price in original currency |
sale_currency | string | Original currency |
usd_price_decimal | double | Price converted to USD |
sale_date | string | Auction date |
sale_location | string | Auction city |
sale_location_country | string | Country |
status | string | Lot status |
sale_estimates_low_usd_price | double | Low estimate in USD |
sale_estimates_high_usd_price | double | High estimate in USD |
gem_type | string | Gemstone type (Diamond, Ruby, Sapphire, Emerald, etc.) |
carats | double | Carat weight |
color | string | Gemstone color |
gemstone_cut | string | Cut type |
gemstone_clarity | string | Clarity grade |
origin | string | Country / region of origin |
certification | string | Certification lab (GIA, SSEF, Gübelin, etc.) |
item_image | string | Primary image URL |
lot_url | string | Original lot URL |
automobile
| Column | Type | Description |
|---|---|---|
item_title | string | Lot title from the auction listing |
manufacturer_name | string | Canonical manufacturer (Ferrari, Porsche, Mercedes-Benz, etc.) |
brand_name | string | Raw brand name as listed |
model | string | Full model designation including sub-model and body variant (e.g. V8 Vantage Volante, 911 Carrera) |
model_family | string | Base-model grouping derived from model for records-per-model depth (911 Turbo and 911 Carrera both map to 911) |
production_year | string | Model year |
vin | string | Chassis / VIN identifier where published by the vendor |
vendor | string | Auction house (Barrett-Jackson, RM Sotheby's, Bonhams Cars, etc.) |
sale_price | double | Hammer price in original sale currency |
sale_currency | string | Original currency |
usd_price_decimal | double | Price converted to USD |
sale_date | string | Auction date (YYYY-MM-DD) |
sale_location | string | Auction city |
sale_location_country | string | Country |
sale_location_state | string | State (US sales) |
status | string | Lot status (Sold, Unsold, Withdrawn, etc.) |
sale_estimates_low_usd_price | string | Low estimate in USD |
sale_estimates_high_usd_price | string | High estimate in USD |
company_name | string | Manufacturer parent company |
company_country | string | Country of the manufacturer |
item_type | string | Lot type (Car, Automobilia, etc.) |
item_type_gemini | string | Gemini-classified item type |
lot_url | string | Original auction lot URL |
item_image | string | Primary image URL |
motorcycle
| Column | Type | Description |
|---|---|---|
item_title | string | Lot title |
manufacturer_name | string | Canonical manufacturer (Harley-Davidson, Ducati, BMW, etc.) |
brand_name | string | Raw brand name |
model | string | Model name |
production_year | string | Model year |
vendor | string | Auction house |
sale_price | double | Hammer price in original currency |
sale_currency | string | Original currency |
usd_price_decimal | double | Price converted to USD |
sale_date | string | Auction date |
sale_location | string | Auction city |
sale_location_country | string | Country |
status | string | Lot status |
company_name | string | Manufacturer parent company |
item_type | string | Lot type |
lot_url | string | Original lot URL |
item_image | string | Primary image URL |
aircraft
| Column | Type | Description |
|---|---|---|
item_title | string | Listing title |
manufacturer_name | string | Manufacturer (Gulfstream, Bombardier, Cessna, etc.) |
model | string | Model name (G650, Global 7500, Citation X, etc.) |
production_year | bigint | Year of manufacture |
vendor | string | Listing source / broker |
sale_price | double | Asking or sale price in original currency |
sale_currency | string | Original currency |
sale_date | string | Listing or sale date |
sale_location | string | Listing location |
sale_country | string | Country |
status | string | Listing status |
sale_estimates_low | double | Low estimate |
sale_estimates_high | double | High estimate |
engine_manufacturer | string | Engine maker |
engine_model | string | Engine model |
range_nm | string | Range in nautical miles |
max_cruise_speed_knots | string | Max cruise speed (knots) |
max_takeoff_weight_lbs | string | Max takeoff weight (lbs) |
typical_passengers | string | Typical passenger count |
cabin_height_feet | string | Cabin height (ft) |
cabin_length_feet | string | Cabin length (ft) |
cabin_width_feet | string | Cabin width (ft) |
total_time_hours | string | Airframe total time (hours) |
serial_no | string | Serial number |
sale_url | string | Original listing URL |
item_image | string | Primary image URL |
wine_whisky
| Column | Type | Description |
|---|---|---|
item_title | string | Lot title |
producer | string | Canonical producer name |
wine_producer | string | Producer as originally listed |
alcohol_type | string | Category (Wine, Whisky, Spirits, etc.) |
color | string | Wine color (Red, White, Rosé) where applicable |
production_year | string | Vintage / production year |
vendor | string | Auction house |
sale_price | string | Hammer price in original currency |
sale_currency | string | Original currency |
usd_price_decimal | double | Price converted to USD |
sale_date | string | Auction date |
sale_location | string | Auction city |
sale_location_country | string | Country |
status | string | Lot status |
sale_estimates_low_usd_price | double | Low estimate in USD |
sale_estimates_high_usd_price | double | High estimate in USD |
item_type | string | Lot type |
lot_url | string | Original lot URL |
item_image | string | Primary image URL |
Endpoints #
The API exposes five endpoints. Replace {name} with any of the datasets listed above. Availability depends on which tables your API key authorizes.
| Method | Path | Auth | Description |
|---|---|---|---|
| GET | /v1/health | No | Service health check |
| GET | /v1/tables | Yes | List available tables |
| GET | /v1/tables/{name}/schema | Yes | Get column names & types |
| GET | /v1/tables/{name}/query | Yes | Simple query via URL params |
| POST | /v1/tables/{name}/query | Yes | Advanced query with filters, sorting, pagination |
GET /v1/health
curl https://api.altfndata.com/v1/health{
"status": "healthy",
"version": "1.0.0",
"timestamp": "2026-03-04T13:00:00.000000+00:00",
"athena_database": "altfinancedb"
}GET /v1/tables
curl -H "X-API-Key: YOUR_KEY" https://api.altfndata.com/v1/tables{
"tables": [
{"name": "watches", "description": "Luxury watch auction results", "column_count": 66},
{"name": "handbags", "description": "Luxury handbag auction results", "column_count": 50},
{"name": "jewelry", "description": "Jewelry and gemstone auction results", "column_count": 57},
{"name": "gems", "description": "Gemstone auction results", "column_count": 58},
{"name": "automobile", "description": "Collector car auction results", "column_count": 60},
{"name": "motorcycle", "description": "Collector motorcycle auction results", "column_count": 48},
{"name": "aircraft", "description": "Aircraft auction results", "column_count": 84},
{"name": "wine_whisky", "description": "Wine and whisky auction results", "column_count": 45}
]
}Only tables authorized for your key appear in the response.
GET /v1/tables/{name}/schema
curl -H "X-API-Key: YOUR_KEY" https://api.altfndata.com/v1/tables/watches/schema{
"table": "watches",
"columns": [
{"name": "item_title", "type": "string"},
{"name": "designer", "type": "string"},
{"name": "usd_price_decimal", "type": "double"},
{"name": "sale_date", "type": "string"}
]
}Querying Data #
POST /v1/tables/{name}/query (recommended)
Full control over field selection, filters, sorting, and pagination.
Request body
{
"fields": ["item_title", "designer", "usd_price_decimal", "sale_date", "vendor"],
"filters": [
{"field": "designer", "op": "eq", "value": "Rolex"},
{"field": "usd_price_decimal", "op": "gte", "value": 50000}
],
"sort": [
{"field": "usd_price_decimal", "direction": "desc"}
],
"limit": 20,
"offset": 0
}| Field | Type | Default | Description |
|---|---|---|---|
fields | string[] | null | null (all columns) | Columns to return |
filters | FilterItem[] | null | null (no filter) | WHERE conditions (AND-ed together) |
sort | SortItem[] | null | null (no ordering) | ORDER BY clauses |
limit | int (1–1000) | 100 | Max rows to return |
offset | int (≥ 0) | 0 | Rows to skip (pagination) |
FilterItem
{"field": "column_name", "op": "eq", "value": "some_value"}SortItem
{"field": "column_name", "direction": "desc"}Response
{
"table": "watches",
"query_execution_id": "ae3d3e58-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
"execution_time_ms": 1505,
"result_count": 5,
"limit": 20,
"offset": 0,
"fields": ["item_title", "designer", "usd_price_decimal", "sale_date", "vendor"],
"data": [
{
"item_title": "Ref.6239, Cosmograph Daytona \"Paul Newman\"",
"designer": "Rolex",
"usd_price_decimal": 17752500.0,
"sale_date": "-",
"vendor": "Phillips"
}
]
}GET /v1/tables/{name}/query (simplified)
For simple queries, use URL parameters:
curl -H "X-API-Key: YOUR_KEY" \
"https://api.altfndata.com/v1/tables/watches/query?designer=Rolex&limit=5&sort=usd_price_decimal:desc"| Parameter | Description |
|---|---|
fields | Comma-separated column names: fields=item_title,vendor,usd_price_decimal |
sort | Column and direction: sort=usd_price_decimal:desc |
limit | Max rows (default 100, max 1000) |
offset | Skip N rows |
| Any column name | Equality filter: designer=Rolex becomes WHERE designer = 'Rolex' |
Pagination
Use limit and offset to page through results:
Page 1: limit=100&offset=0
Page 2: limit=100&offset=100
Page 3: limit=100&offset=200When result_count < limit, you've reached the last page.
Filter Operators #
All filters use the "op" key. Multiple filters are AND-ed together.
| Operator | Description | Value Type | Example |
|---|---|---|---|
eq | Equals | scalar | {"field": "designer", "op": "eq", "value": "Rolex"} |
neq | Not equals | scalar | {"field": "status", "op": "neq", "value": "withdrawn"} |
gt | Greater than | numeric | {"field": "usd_price_decimal", "op": "gt", "value": 100000} |
gte | Greater or equal | numeric | {"field": "carats", "op": "gte", "value": 5} |
lt | Less than | numeric | {"field": "usd_price_decimal", "op": "lt", "value": 1000} |
lte | Less or equal | numeric | {"field": "usd_price_decimal", "op": "lte", "value": 1000} |
like | Contains (case-insensitive) | string | {"field": "item_title", "op": "like", "value": "Daytona"} |
in | In list | array | {"field": "vendor", "op": "in", "value": ["Christie's", "Sotheby's"]} |
not_in | Not in list | array | {"field": "vendor", "op": "not_in", "value": ["eBay"]} |
is_null | Is NULL | none | {"field": "usd_price_decimal", "op": "is_null"} |
is_not_null | Is not NULL | none | {"field": "usd_price_decimal", "op": "is_not_null"} |
Values for numeric operators (gt, gte, lt, lte) are auto-cast to double.
Valuation API #<
Fine Art
Fine art auction results across all movements and periods
Works of Art
Works of art with stone/jewelry relevance (jade, jadeite, diamond-set, etc.)
Design
Design and decorative arts — furniture, lighting (incl. Tiffany Studios lamps), glass, ceramics, and...
Books
Books, manuscripts, maps and printed material.
Coins
Numismatic coin auction results.
Automobilia
Automobilia — automotive memorabilia, parts, signage, models and related collectibles (not the cars themselves;...
Fashion
Fashion and couture — clothing and accessories (not handbags or shoes, which have their own tables).
Shoes
Footwear — designer shoes and collectible sneakers.
Other Automobile
Other vehicles -- non-car, non-motorcycle (boats, tractors, trucks, buses, military).
Perfume
Perfume and collectible fragrance bottles / flacons.
Accessories
Fashion accessories -- belts, scarves, cufflinks, brooches, sunglasses (incl. gem-set pieces).
Musical Instruments
Musical instruments -- guitars, violin family, pianos and keyboards, woodwind, brass, percussion, amplifiers.
/h2>
The Valuation API returns a valuation and the comparable sales that support it for a luxury or collectible item. You send an item's attributes; we return a price range, a confidence score, and the comps behind it. The dataset stays on our side, so you receive the answer and supporting comparables rather than raw records. Valuation is included on Professional and above plans, so your existing API key carries it, with no separate key required. It is metered separately from your data row quota, where one valuation counts as one unit.
| Method | Path | Auth | Description |
|---|---|---|---|
| POST | /v1/valuation | Yes | Value an item and return supporting comps |
| POST | /v1/valuation/batch | Yes | Value up to 25 items in one call |
| GET | /v1/valuation/history | Yes | Median price over time for a brand and model |
| GET | /v1/valuation/liquidity | Yes | Sell-through and buy-in rate for a brand and model |
| GET | /v1/valuation/adjustments | Yes | Value by attribute (hardware, material) vs the model baseline |
| GET | /v1/valuation/forecast | Yes | Projected value trajectory from auction history |
| GET | /v1/valuation/models | Yes | List models we can value for a brand |
POST /v1/valuation
Send structured attributes (recommended) or a lot URL / free-text description in input. More attributes yield a tighter comp set.
| Field | Type | Notes |
|---|---|---|
category | string | handbags, watches, cars, jewelry, gems, wine, motorcycles, fine art, fashion. Default handbags. |
brand | string | e.g. Hermès. Recommended. |
model | string | e.g. Birkin 25. Recommended. |
material | string | e.g. togo, epsom. Optional. |
size | string | e.g. 25, 30. Optional. |
hardware | string | e.g. gold, palladium. Optional. |
color | string | e.g. black, etoupe. Optional. |
input | string | A lot URL or free-text description; takes precedence if present. |
asking_price | number | An asking or listing price. When given, the response includes a fair-price verdict. |
asking_currency | string | Currency of asking_price. Default USD. |
curl https://api.altfndata.com/v1/valuation \
-H "X-API-Key: YOUR_KEY" -H "Content-Type: application/json" \
-d '{"category":"handbags","brand":"Herm\u00e8s","model":"Birkin 25","material":"togo","hardware":"gold","color":"black"}'{
"ok": true,
"category": "handbags",
"query": { "brand": "Herm\u00e8s", "model": "Birkin 25", "size": "25", "material": "leather", "hardware": "gold", "color": "black" },
"valuation": { "median": 23999, "low": 12567, "high": 52324, "p25": 18000, "p75": 30000, "count": 529, "currency": "USD" },
"confidence": "high",
"confidence_score": 0.99,
"comps": [
{ "vendor": "Sotheby's", "sale_date": "2026-01-14", "usd_price": 24000, "model": "Birkin 25", "material": "leather", "lot_url": "https://..." }
]
}Valuations are in USD. median is the headline figure, low/high the range, p25/p75 the interquartile band, and count the number of comparable sales used. confidence is low, medium or high; confidence_score runs 0 to 1. comps are the supporting comparable sales, licensed for display. If there are too few comparables, ok is false with a reason. When available, price_history gives the median-by-year series with a direction and percentage change. When an asking_price was supplied, verdict reports whether it is below, in line with, or above the market, with the difference against the median.
POST /v1/valuation/batch
Value many items in one call. items is an array where each entry takes the same fields as a single valuation. Up to 25 items per call. Each valuation is metered as one unit; a bad item is returned as ok: false with an error rather than failing the batch.
curl https://api.altfndata.com/v1/valuation/batch \n -H "X-API-Key: YOUR_KEY" -H "Content-Type: application/json" \n -d '{"items":[{"brand":"Hermès","model":"Birkin 25"},{"brand":"Chanel","model":"Classic Flap Medium"}]}'Returns { "count", "valued", "results": [ ... ] }, one result per item in order.
GET /v1/valuation/history
Median price over time for a brand and model, for charting a value trajectory without running a full item valuation. Returns the current valuation summary plus a median-by-year series. Metered as one call.
curl "https://api.altfndata.com/v1/valuation/history?brand=Hermès&model=Birkin%2025&category=handbags" \n -H "X-API-Key: YOUR_KEY"GET /v1/valuation/liquidity
Sell-through and buy-in rate for a brand and model: of the lots offered at auction, the share that sold. Marketplace listings and withdrawn or unconfirmed lots are excluded, so this reflects auction demand. Returns sell_through_rate, buy_in_rate, and the underlying sold / unsold / offered counts. Below a small sample, the rate is null with a note.
curl "https://api.altfndata.com/v1/valuation/liquidity?brand=Hermès&model=Birkin&category=handbags" \n -H "X-API-Key: YOUR_KEY"GET /v1/valuation/adjustments
How value shifts by attribute for a brand and model: the median for each hardware and material, expressed as vs_baseline_pct against the model's overall median. The appraiser view of what each feature is worth. Handbags for now.
curl "https://api.altfndata.com/v1/valuation/adjustments?brand=Hermès&model=Birkin&category=handbags" \n -H "X-API-Key: YOUR_KEY"GET /v1/valuation/forecast
Projects a model's median value forward from its auction history, with a confidence band. horizon is 1 to 5 years (default 3). Returns the historical CAGR and volatility alongside the projection. This is a trend estimate, not a guarantee.
curl "https://api.altfndata.com/v1/valuation/forecast?brand=Hermès&model=Birkin&horizon=3" \n -H "X-API-Key: YOUR_KEY"GET /v1/valuation/models
Lists the models we can value for a brand. Item identification is attribute-based; there is no fixed catalogue of item IDs. This returns the models with enough comparable sales to value.
curl "https://api.altfndata.com/v1/valuation/models?brand=Herm\u00e8s&category=handbags" \
-H "X-API-Key: YOUR_KEY"Rate Limits #
Usage limits vary by subscription tier.
| Limit | Student | Professional | Business | Institutional |
|---|---|---|---|---|
| Requests per minute | 20 | 30 | 60 | 60 |
| Rows per day | 2,500 | 10,000 | 25,000 | 50,000+ |
| Rows per month | 2,500 | 50,000 | 150,000 | Negotiated |
| Max rows per request | 100 | 100 | 250 | 500 |
| Bulk export | ✘ | ✘ | ✘ | Contract-governed |
| Valuations per day | ✘ | 300 | 1,000 | Negotiated |
| Valuations per month | ✘ | 5,000 | 20,000 | Negotiated |
Quotas are enforced per table: the daily cap resets at midnight UTC, and the monthly cap resets on the 1st (UTC). Valuations are metered separately against your plan's valuation allowance, one unit per valuation.
When limits are exceeded, you receive HTTP 429:
{"detail": "Rate limit exceeded (30 requests/minute). Try again later."}{"detail": "Daily row quota exceeded for watches (10,000 rows/day). Resets at midnight UTC."}{"detail": "Monthly row quota exceeded for watches (150,000 rows/month). Resets on the 1st (UTC)."}Error Handling #
| Status | Cause | Example Response |
|---|---|---|
400 | Invalid column, operator, or value | {"detail": "Unknown column: invalid_col"} |
401 | Missing API key | {"detail": "Missing API key"} |
403 | Invalid key or unauthorized table | {"detail": "Invalid API key"} |
404 | Table not found | {"detail": "Table not found: yachts"} |
429 | Rate limit or quota exceeded | {"detail": "Rate limit exceeded..."} |
500 | Athena query failure | {"detail": "Athena query failed: ..."} |
All error responses return JSON with a "detail" key. For 500 errors, a "query_execution_id" is also included for debugging.
Code Examples #
curl
# List tables
curl -H "X-API-Key: YOUR_KEY" https://api.altfndata.com/v1/tables
# Simple GET query
curl -H "X-API-Key: YOUR_KEY" \
"https://api.altfndata.com/v1/tables/watches/query?designer=Rolex&limit=10&sort=usd_price_decimal:desc"
# POST query with filters
curl -X POST https://api.altfndata.com/v1/tables/watches/query \
-H "X-API-Key: YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{
"fields": ["item_title", "designer", "vendor", "usd_price_decimal", "sale_date"],
"filters": [
{"field": "designer", "op": "eq", "value": "Rolex"},
{"field": "usd_price_decimal", "op": "gte", "value": 50000}
],
"sort": [{"field": "usd_price_decimal", "direction": "desc"}],
"limit": 20
}'Python
import requests
API_KEY = "YOUR_KEY"
BASE = "https://api.altfndata.com"
HEADERS = {"X-API-Key": API_KEY}
# List tables
tables = requests.get(f"{BASE}/v1/tables", headers=HEADERS).json()
for t in tables["tables"]:
print(f"{t['name']}: {t['column_count']} columns")
# Get schema
schema = requests.get(f"{BASE}/v1/tables/watches/schema", headers=HEADERS).json()
for col in schema["columns"][:10]:
print(f" {col['name']}: {col['type']}")
# Query: Top 10 Rolex watches by price
resp = requests.post(
f"{BASE}/v1/tables/watches/query",
headers={**HEADERS, "Content-Type": "application/json"},
json={
"fields": ["item_title", "vendor", "usd_price_decimal", "sale_date"],
"filters": [
{"field": "designer", "op": "eq", "value": "Rolex"},
{"field": "usd_price_decimal", "op": "is_not_null"},
],
"sort": [{"field": "usd_price_decimal", "direction": "desc"}],
"limit": 10,
},
)
data = resp.json()
print(f"\n{data['result_count']} results ({data['execution_time_ms']}ms)\n")
for row in data["data"]:
print(f" ${row['usd_price_decimal']:,.0f} {row['vendor']} {row['item_title'][:60]}")
# Pagination
all_results = []
offset = 0
while True:
resp = requests.post(
f"{BASE}/v1/tables/watches/query",
headers={**HEADERS, "Content-Type": "application/json"},
json={
"fields": ["item_title", "usd_price_decimal"],
"filters": [{"field": "designer", "op": "eq", "value": "Patek Philippe"}],
"sort": [{"field": "usd_price_decimal", "direction": "desc"}],
"limit": 100,
"offset": offset,
},
)
page = resp.json()
all_results.extend(page["data"])
if page["result_count"] < 100:
break
offset += 100
print(f"Total Patek Philippe records: {len(all_results)}")JavaScript / Node.js
const API_KEY = "YOUR_KEY";
const BASE = "https://api.altfndata.com";
// List tables
const tables = await fetch(`${BASE}/v1/tables`, {
headers: { "X-API-Key": API_KEY },
}).then((r) => r.json());
console.log(tables);
// Query watches
const resp = await fetch(`${BASE}/v1/tables/watches/query`, {
method: "POST",
headers: {
"X-API-Key": API_KEY,
"Content-Type": "application/json",
},
body: JSON.stringify({
fields: ["item_title", "designer", "usd_price_decimal", "vendor"],
filters: [
{ field: "designer", op: "eq", value: "Omega" },
{ field: "usd_price_decimal", op: "gte", value: 10000 },
],
sort: [{ field: "usd_price_decimal", direction: "desc" }],
limit: 10,
}),
}).then((r) => r.json());
console.log(`${resp.result_count} results (${resp.execution_time_ms}ms)`);
resp.data.forEach((row) => {
console.log(` $${row.usd_price_decimal} ${row.item_title}`);
});MCP Server for AI assistants #
The ALT/FNDATA MCP server lets your AI assistant query the API directly in conversation. Instead of writing code, just ask questions in natural language. It uses the open Model Context Protocol (MCP), so it works with Claude, ChatGPT, Gemini, Perplexity and other assistants and developer tools that support MCP servers.
Option 1: Connect the hosted server (no install)
In any assistant that supports remote MCP servers (often called custom connectors), add a connector with this URL:
https://mcp.altfndata.com/mcpChoose OAuth if you are asked for an authentication method. When you connect, a sign-in page asks for your ALT/FNDATA API key. Get your key from API Key & MCP in the app.
- Claude: Settings → Connectors → add a custom connector.
- ChatGPT: add it as a custom connector (developer mode). ChatGPT only connects to hosted servers, so use this option.
- Perplexity: Settings → Connectors → add a custom connector with the URL above.
- Gemini app: Settings → Connected Apps → add a custom app with the URL above (personal Google accounts).
- Gemini Enterprise: an admin adds ALT/FNDATA once for the organisation. See Gemini Enterprise set-up below.
Menu names and plan availability are set by each assistant and change over time. Check its help pages if the steps differ.
Gemini Enterprise (admin set-up)
Gemini Enterprise connects through a Custom MCP Server data store, which an admin sets up once for the organisation.
- Register a client. The response contains a
client_idand aclient_secret. The secret is shown only once, so store it safely.bashcurl -X POST https://mcp.altfndata.com/register \ -H "Content-Type: application/json" \ -d '{"client_name": "Gemini Enterprise (your organisation)", "redirect_uris": ["https://vertexaisearch.cloud.google.com/oauth-redirect"], "token_endpoint_auth_method": "client_secret_post", "grant_types": ["authorization_code", "refresh_token"], "response_types": ["code"], "scope": "read"}' - In the Gemini Enterprise console, add a Custom MCP Server data store with these values:
Field Value MCP Server URL https://mcp.altfndata.com/mcpAuthorization URL https://mcp.altfndata.com/authorizeToken URL https://mcp.altfndata.com/tokenClient ID client_idfrom step 1Client Secret client_secretfrom step 1Scopes readEnable PKCE ticked - Each user then connects from Gemini and signs in with their own ALT/FNDATA API key. The client ID and secret only identify your organisation's Gemini Enterprise; they give no access to data on their own.
Google's guide to setting up a custom MCP server describes the console screens.
Option 2: Run it locally
For desktop apps and developer tools that launch MCP servers on your machine.
pip install altfinance-mcpRequires Python 3.10+. Most tools take a configuration in this shape; add it to the tool's MCP settings and restart it:
{
"mcpServers": {
"altfinance": {
"command": "altfinance-mcp",
"env": {
"ALTFINANCE_API_KEY": "YOUR_KEY"
}
}
}
}Example: Claude Desktop
Add the configuration above to the Claude Desktop config file, then restart Claude Desktop:
- macOS:
~/Library/Application Support/Claude/claude_desktop_config.json - Windows:
%APPDATA%\Claude\claude_desktop_config.json
Example: Claude Code
export ALTFINANCE_API_KEY="YOUR_KEY"
claude mcp add altfinance -- altfinance-mcpMCP Tools
The server exposes 9 read-only tools. Every tool is annotated readOnlyHint and openWorldHint, and no tool modifies data.
| Tool | Parameters | Returns |
|---|---|---|
list_tables() | none | Every table, with live descriptions and column counts |
get_table_schema(table) | table | Column names and types for one table |
query_table(table, fields, filters, sort_field, sort_direction, limit, offset) | table required; filters use field/op/value; limit max 500 | Matching rows with filtering, sorting, field selection, and pagination |
market_stats(table, filters, sold_only) | table required; optional filters; sold_only defaults true | Count of sales, median, 25th/75th percentiles, average, min/max USD, sale-date span, and top vendors by volume, computed server-side over the full matching set |
price_trend(table, filters, by, sold_only) | by is year (default), quarter, or month | Per-period count, median, and average realized price |
price_check(description, lot_url, category) | Give a description or a lot_url; category is handbags, watches, or cars (inferred if omitted) | Fair-value range (low / median / high), a confidence read, and comparable sales with source links, for one item. Loose stones and jewelry are intentionally held from comp-matching |
search(query, category, filters, limit) | query keywords; optional category hint; limit max 100 | Whole-market keyword search across every category at once, merged by realized price. With no category it fans out across every table |
market_index(query, brand, category) | A model query or a brand; category is handbags, watches, or cars | Precomputed model-level index (low / 25th / median / 75th / high), sample size, and trend. Other categories are redirected to market_stats or price_trend |
list_alerts(limit) | limit defaults 25 | Read-only view of fired price alerts when reachable, otherwise guidance on enabling alerts in the app. See Limits and caveats |
Datasets and fields
The database spans 20 tables. Call list_tables for the live set with current column counts.
| Table | Description |
|---|---|
watches | Luxury watch auction results |
handbags | Luxury handbag auction results |
jewelry | Finished jewelry, mounted pieces (rings, necklaces, bracelets, earrings) set with gemstones |
gems | Loose, unmounted gemstones (single stones and parcels). Use this for gemstone valuations, not jewelry |
automobile | Collector car auction results |
motorcycle | Collector motorcycle auction results |
aircraft | Aircraft auction results |
wine_whisky | Wine and whisky auction results |
works_of_art | Works of art with stone/jewelry relevance (jade, jadeite, diamond-set, etc.) |
fine_art | Fine art auction results across all movements and periods |
design | Design and decorative arts: furniture, lighting, glass, ceramics, studio/industrial design |
fashion | Fashion and couture: clothing and accessories (not handbags or shoes) |
shoes | Footwear: designer shoes and collectible sneakers |
automobilia | Automotive memorabilia, parts, signage, models and related collectibles (not the cars themselves) |
books | Books, manuscripts, maps and printed material |
coins | Numismatic coin auction results |
other_automobile | Other vehicles: boats, tractors, trucks, buses and military vehicles (not cars or motorcycles) |
perfume | Perfume and collectible fragrance bottles and flacons |
accessories | Fashion accessories: belts, scarves, cufflinks, brooches and sunglasses, including gem-set pieces |
musical_instruments | Musical instruments: guitars, violin family, pianos and keyboards, woodwind, brass, percussion and amplifiers |
gems vs jewelry: gems holds LOOSE, unmounted stones (the right table for a gemstone valuation); jewelry holds FINISHED, mounted pieces set with stones. If one returns nothing, try the other.
Limits and caveats
- Price alerts are read-only over MCP. Alerts and the watchlist belong to a signed-in ALT/FNDATA account (Cognito login), not to an API key. The MCP authenticates with an API key only, so it cannot create or enable alerts, and even reading requires the alerts feed to be reachable, otherwise
list_alertsreturns setup guidance rather than a feed. Manage alerts in the app at app.altfndata.com. Allowance by plan: free 0, registered 1, collector 10, pro 100, included with Membership. - Occasional suggestions. Some tool responses may append a single short "💡" line suggesting a complementary product or a plan upgrade. It appears at most once per response, only at a genuine tier boundary (a table your plan does not include, or an exhausted row quota) or as a relevant feature tip, and never for unlimited or comp accounts. It never changes the data returned.
- Percentiles and medians in
market_statsandprice_trendare computed server-side over the full matching set, not sampled client-side, so they reflect the whole market rather than the rows returned. - Read-only. Every tool is annotated
readOnlyHint; the MCP never writes.
Example Prompts
Once connected, ask your assistant:
- "What tables are available in the ALT/FNDATA database?"
- "Give me market stats for Rolex Daytona watches"
- "How have Hermes Birkin prices moved by year?"
- "Price-check a Rolex Daytona 116500 white dial"
- "Search the whole market for a Burma ruby ring over $50k"
- "What loose sapphires have sold at auction?" (this uses
gems, notjewelry)
The assistant calls the right tools, handles schemas, and formats the results.
Environment Variables
| Variable | Required | Default |
|---|---|---|
ALTFINANCE_API_KEY | Yes | — |
ALTFINANCE_API_URL | No | https://api.altfndata.com |