{
  "info": {
    "name": "Grail — eBay Sold Comps API",
    "description": "Real eBay sold listings as an API. One call returns up to 240 completed sales plus a median and range. Set your `grail_key` variable (free key at https://grail.solutions/signup) and run. Docs: https://grail.solutions/docs",
    "schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json"
  },
  "auth": {
    "type": "bearer",
    "bearer": [{ "key": "token", "value": "{{grail_key}}", "type": "string" }]
  },
  "event": [
    {
      "listen": "prerequest",
      "script": {
        "type": "text/javascript",
        "exec": [
          "if (!pm.variables.get('grail_key') || pm.variables.get('grail_key').indexOf('grail_') !== 0) {",
          "  console.warn('Set the grail_key collection variable to a real Grail API key.');",
          "}"
        ]
      }
    }
  ],
  "variable": [
    { "key": "baseUrl", "value": "https://grail.solutions" },
    { "key": "grail_key", "value": "grail_your_key_here" }
  ],
  "item": [
    {
      "name": "Sold comps — one keyword",
      "request": {
        "method": "GET",
        "header": [],
        "url": {
          "raw": "{{baseUrl}}/v1/scrape?keyword=leica+m6&count=60&sold=true",
          "host": ["{{baseUrl}}"],
          "path": ["v1", "scrape"],
          "query": [
            { "key": "keyword", "value": "leica m6" },
            { "key": "count", "value": "60", "description": "1–240" },
            { "key": "sold", "value": "true", "description": "true = completed sales" },
            { "key": "relevance", "value": "false", "description": "false = raw eBay feed (default)" },
            { "key": "ebaySite", "value": "ebay.com", "disabled": true }
          ]
        },
        "description": "Returns items[] (up to 240 sold rows) plus rawMedian / rawSampleCount and a summary block."
      }
    },
    {
      "name": "Sold comps — cleaned median",
      "request": {
        "method": "GET",
        "header": [],
        "url": {
          "raw": "{{baseUrl}}/v1/scrape?keyword=charizard+base+set&count=240&relevance=true",
          "host": ["{{baseUrl}}"],
          "path": ["v1", "scrape"],
          "query": [
            { "key": "keyword", "value": "charizard base set" },
            { "key": "count", "value": "240" },
            { "key": "relevance", "value": "true", "description": "strip accessories/parts before the median" }
          ]
        },
        "description": "Same endpoint with relevance cleaning on — median over the cleaned set."
      }
    },
    {
      "name": "Bulk — many keywords",
      "request": {
        "method": "POST",
        "header": [{ "key": "Content-Type", "value": "application/json" }],
        "body": {
          "mode": "raw",
          "raw": "{\n  \"keywords\": [\"leica m6\", \"iphone 15 pro\", \"nintendo switch oled\"],\n  \"count\": 60,\n  \"relevance\": true\n}"
        },
        "url": {
          "raw": "{{baseUrl}}/v1/scrape/bulk",
          "host": ["{{baseUrl}}"],
          "path": ["v1", "scrape", "bulk"]
        },
        "description": "Up to 25 keywords in one call, each cache-first and metered once."
      }
    },
    {
      "name": "Shipping rates",
      "request": {
        "method": "POST",
        "header": [{ "key": "Content-Type", "value": "application/json" }],
        "body": { "mode": "raw", "raw": "{\n  \"keyword\": \"leica m6\"\n}" },
        "url": {
          "raw": "{{baseUrl}}/v1/shipping/rates",
          "host": ["{{baseUrl}}"],
          "path": ["v1", "shipping", "rates"]
        },
        "description": "Observed shipping for a keyword plus a labelled landed-cost estimate."
      }
    },
    {
      "name": "Usage",
      "request": {
        "method": "GET",
        "header": [],
        "url": {
          "raw": "{{baseUrl}}/v1/usage",
          "host": ["{{baseUrl}}"],
          "path": ["v1", "usage"]
        },
        "description": "Current key usage, plan, monthly quota and reset window."
      }
    }
  ]
}