Documentation
Swagger UI altfndata.com

AltFinance Data API

Access 990,000+ luxury auction records across watches, handbags, and jewelry from 100+ auction houses worldwide — including Christie's, Sotheby's, Phillips, Bonhams, and more.

Base URL

https://api.altfndata.com

Recommended path for new developers

Follow these steps to go from zero to a working integration.

1

Get your API key

Your key is provided in your welcome email. Set it in the X-API-Key header for all requests.

Go to Authentication →
2

Make your first API call

Use the POST query endpoint to search across watches, handbags, or jewelry with filters and sorting.

Go to Querying Data →
3

Explore the datasets

Browse available tables, understand the columns, and discover what data you can query.

See Available Tables →

Build with the API

Available datasets


Tools & Integrations


Authentication #

All endpoints except /v1/health require an API key. Pass your key in the X-API-Key header:

Header
X-API-Key: afi_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

Your API key is provided in your welcome email. Keep it secret — do not commit it to source control or share it publicly.

ScenarioHTTP StatusResponse
Key missing401{"detail": "Missing API key"}
Key invalid or inactive403{"detail": "Invalid API key"}
Key lacks table access403{"detail": "No access to table: watches"}

Endpoints #

The API exposes five endpoints. Replace {name} with watches, handbags, or jewelry.

MethodPathAuthDescription
GET/v1/healthNoService health check
GET/v1/tablesYesList available tables
GET/v1/tables/{name}/schemaYesGet column names & types
GET/v1/tables/{name}/queryYesSimple query via URL params
POST/v1/tables/{name}/queryYesAdvanced query with filters, sorting, pagination

GET /v1/health

GET/v1/health
bash
curl https://api.altfndata.com/v1/health
json
{
  "status": "healthy",
  "version": "1.0.0",
  "timestamp": "2026-03-04T13:00:00.000000+00:00",
  "athena_database": "altfinancedb"
}

GET /v1/tables

GET/v1/tables
bash
curl -H "X-API-Key: YOUR_KEY" https://api.altfndata.com/v1/tables
json
{
  "tables": [
    {"name": "watches",  "description": "Luxury watch auction results",   "column_count": 122},
    {"name": "handbags", "description": "Luxury handbag auction results",  "column_count": 67},
    {"name": "jewelry",  "description": "Jewelry and gemstone auction results", "column_count": 99}
  ]
}

GET /v1/tables/{name}/schema

GET/v1/tables/{name}/schema
bash
curl -H "X-API-Key: YOUR_KEY" https://api.altfndata.com/v1/tables/watches/schema
json
{
  "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)

POST/v1/tables/{name}/query

Full control over field selection, filters, sorting, and pagination.

Request body

json
{
  "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
}
FieldTypeDefaultDescription
fieldsstring[] | nullnull (all columns)Columns to return
filtersFilterItem[] | nullnull (no filter)WHERE conditions (AND-ed together)
sortSortItem[] | nullnull (no ordering)ORDER BY clauses
limitint (1–1000)100Max rows to return
offsetint (≥ 0)0Rows to skip (pagination)

FilterItem

json
{"field": "column_name", "op": "eq", "value": "some_value"}

SortItem

json
{"field": "column_name", "direction": "desc"}

Response

json
{
  "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)

GET/v1/tables/{name}/query

For simple queries, use URL parameters:

bash
curl -H "X-API-Key: YOUR_KEY" \
  "https://api.altfndata.com/v1/tables/watches/query?designer=Rolex&limit=5&sort=usd_price_decimal:desc"
ParameterDescription
fieldsComma-separated column names: fields=item_title,vendor,usd_price_decimal
sortColumn and direction: sort=usd_price_decimal:desc
limitMax rows (default 100, max 1000)
offsetSkip N rows
Any column nameEquality filter: designer=Rolex becomes WHERE designer = 'Rolex'

Pagination

Use limit and offset to page through results:

text
Page 1: limit=100&offset=0
Page 2: limit=100&offset=100
Page 3: limit=100&offset=200

When result_count < limit, you've reached the last page.

Filter Operators #

All filters use the "op" key. Multiple filters are AND-ed together.

OperatorDescriptionValue TypeExample
eqEqualsscalar{"field": "designer", "op": "eq", "value": "Rolex"}
neqNot equalsscalar{"field": "status", "op": "neq", "value": "withdrawn"}
gtGreater thannumeric{"field": "usd_price_decimal", "op": "gt", "value": 100000}
gteGreater or equalnumeric{"field": "carats", "op": "gte", "value": 5}
ltLess thannumeric{"field": "usd_price_decimal", "op": "lt", "value": 1000}
lteLess or equalnumeric{"field": "usd_price_decimal", "op": "lte", "value": 1000}
likeContains (case-insensitive)string{"field": "item_title", "op": "like", "value": "Daytona"}
inIn listarray{"field": "vendor", "op": "in", "value": ["Christie's", "Sotheby's"]}
not_inNot in listarray{"field": "vendor", "op": "not_in", "value": ["eBay"]}
is_nullIs NULLnone{"field": "usd_price_decimal", "op": "is_null"}
is_not_nullIs not NULLnone{"field": "usd_price_decimal", "op": "is_not_null"}

Values for numeric operators (gt, gte, lt, lte) are auto-cast to double.

Available Tables #

Three datasets are available. Use the /v1/tables/{name}/schema endpoint to see all columns for any table.

watches

122 columns · 390K+ records

Luxury watch auction results from major houses worldwide.

handbags

67 columns · 120K+ records

Designer handbag auction results.

jewelry

99 columns · 480K+ records

Jewelry and gemstone auction results.

watches

ColumnTypeDescription
item_titlestringWatch description from the auction listing
designerstringBrand name (Rolex, Patek Philippe, Omega, etc.)
manufacturer_namestringManufacturer (often same as designer)
modelstringModel name (Submariner, Nautilus, etc.)
vendorstringAuction house (Phillips, Sotheby's, Christie's, etc.)
sale_pricedoubleHammer price in original sale currency
sale_currencystringOriginal currency (USD, GBP, EUR, CHF, etc.)
usd_price_decimaldoublePrice converted to USD
sale_datestringAuction date (YYYY-MM-DD)
sale_locationstringAuction city
sale_location_countrystringCountry
statusstringLot status (sold, unsold, withdrawn, etc.)
sale_estimates_low_usd_pricedoubleLow estimate in USD
sale_estimates_high_usd_pricedoubleHigh estimate in USD
case_materialstringCase material (steel, gold, platinum, etc.)
case_diameterstringCase diameter
dial_colorstringDial color
movementstringMovement type
referencestringReference number
item_imagestringPrimary image URL
lot_urlstringOriginal auction lot URL

handbags

ColumnTypeDescription
item_titlestringHandbag description from listing
brand_name_cleanstringStandardized brand name (Hermes, Chanel, Louis Vuitton, etc.)
designerstringDesigner name
modelstringModel name (Birkin, Kelly, Classic Flap, etc.)
vendorstringAuction house
sale_pricedoubleHammer price in original currency
sale_currencystringOriginal currency
usd_price_decimaldoublePrice converted to USD
sale_datestringAuction date
sale_locationstringAuction city
sale_location_countrystringCountry
statusstringLot status
sale_estimates_low_usd_pricedoubleLow estimate in USD
sale_estimates_high_usd_pricedoubleHigh estimate in USD
materialsstringBag materials
item_typestringBag type (Shoulder Bag, Clutch, Tote, etc.)
item_imagestringPrimary image URL
lot_urlstringOriginal lot URL

jewelry

ColumnTypeDescription
item_titlestringJewelry description from listing
designerstringDesigner or brand name
manufacturer_namestringManufacturer
vendorstringAuction house
sale_pricedoubleHammer price in original currency
sale_currencystringOriginal currency
usd_price_decimaldoublePrice converted to USD
sale_datestringAuction date
sale_locationstringAuction city
sale_location_countrystringCountry
statusstringLot status
sale_estimates_low_usd_pricedoubleLow estimate in USD
sale_estimates_high_usd_pricedoubleHigh estimate in USD
gem_typestringGemstone type (Diamond, Ruby, Sapphire, Emerald, etc.)
primary_gemstringPrimary gemstone
caratsdoubleCarat weight
gemstone_cutstringCut type
gemstone_claritystringClarity grade
colorstringGemstone color
item_typestringJewelry type (Ring, Necklace, Bracelet, etc.)
item_imagestringPrimary image URL
lot_urlstringOriginal lot URL

Rate Limits #

Each API key has configurable rate limits:

LimitDescription
Requests per minuteSliding 60-second window; configurable per API key
Daily row quotaTotal rows returned per calendar day (UTC); resets at midnight
Max rows per requestCaps the limit parameter per API key

When limits are exceeded, you receive HTTP 429:

json
{"detail": "Rate limit exceeded (30 requests/minute). Try again later."}
json
{"detail": "Daily row quota exceeded (10000 rows/day). Resets at midnight UTC."}

Error Handling #

StatusCauseExample Response
400Invalid column, operator, or value{"detail": "Unknown column: invalid_col"}
401Missing API key{"detail": "Missing API key"}
403Invalid key or unauthorized table{"detail": "Invalid API key"}
404Table not found{"detail": "Table not found: cars"}
429Rate limit or quota exceeded{"detail": "Rate limit exceeded..."}
500Athena 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

bash
# 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

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

javascript
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}`);
});

Claude MCP Server #

The AltFinance MCP server lets Claude query the API directly in conversation. Instead of writing code, just ask questions in natural language.

Install

bash
pip install altfinance-mcp

Requires Python 3.10+.

Configure for Claude Desktop

Edit your Claude Desktop config file:

  • macOS: ~/Library/Application Support/Claude/claude_desktop_config.json
  • Windows: %APPDATA%\Claude\claude_desktop_config.json
json
{
  "mcpServers": {
    "altfinance": {
      "command": "altfinance-mcp",
      "env": {
        "ALTFINANCE_API_KEY": "YOUR_KEY"
      }
    }
  }
}

Restart Claude Desktop after saving.

Configure for Claude Code

bash
export ALTFINANCE_API_KEY="YOUR_KEY"
claude mcp add altfinance -- altfinance-mcp

MCP Tools

ToolDescription
list_tables()Shows available tables with column counts
get_table_schema(table)Lists all columns and their types
query_table(table, ...)Queries with full filter support

Example Prompts

Once configured, ask Claude:

  • "What tables are available in the AltFinance database?"
  • "Show me the top 10 most expensive Rolex watches sold after 2020"
  • "How many Hermes handbags were sold by Christie's?"
  • "What diamonds over 5 carats sold for more than $1M?"
  • "Compare average Rolex vs Omega prices by year"

Claude will automatically call the right tools, handle schemas, and format results.

Environment Variables

VariableRequiredDefault
ALTFINANCE_API_KEYYes
ALTFINANCE_API_URLNohttps://api.altfndata.com