Skip to content

Instantly share code, notes, and snippets.

@cwawak
Last active February 27, 2026 13:01
Show Gist options
  • Select an option

  • Save cwawak/7fcaf0abac29e630b9b08ad294ce6d75 to your computer and use it in GitHub Desktop.

Select an option

Save cwawak/7fcaf0abac29e630b9b08ad294ce6d75 to your computer and use it in GitHub Desktop.
Hyundai BSI Inventory API (Unofficial)

Hyundai BSI Inventory API (Unofficial)

Hyundai's dealer inventory search at hyundaiusa.com is backed by an undocumented internal API. This documents the endpoints and patterns discovered through browser network inspection.

Disclaimer: This is an unofficial, reverse-engineered API. It is not publicly documented, has no SLA, and may change without notice. Use responsibly and don't hammer the endpoints.


Inventory Search

Endpoint

POST https://papp-bsi-api.hyundaiusa.com/inventory/item/v2/search

Headers

Content-Type: application/json
Accept: application/json, text/plain, */*

Request Body

{
  "zipCode": "20036",
  "distance": 25,
  "page": 1,
  "pageSize": 30,
  "sort": {
    "attributeName": "distance",
    "order": "asc"
  },
  "atDealershipOnly": false,
  "availableOnline": false,
  "filterTag": "modelName",
  "modelYear": [2026],
  "modelName": [
    {
      "code": "J006",
      "trims": [
        {
          "name": "HEV CALLIGRAPHY",
          "packages": []
        }
      ]
    }
  ]
}

Key Parameters

Parameter Description
zipCode Search center ZIP code
distance Radius in miles
page Page number (1-indexed)
pageSize Results per page — max 30
sort.attributeName Sort field: distance, price, etc.
sort.order asc or desc
atDealershipOnly true = in-stock only
modelYear Array of years
modelName[].code Model code (see table below)
modelName[].trims[].name Trim level string

Model Codes (partial)

Code Model
J006 Palisade
(others vary) Check network tab for your model

Trim Name Format

Trim names follow the pattern "{POWERTRAIN} {TRIM}", e.g.:

  • "HEV CALLIGRAPHY" — Hybrid, Calligraphy trim
  • "HEV SEL CONVENIENCE" — Hybrid, SEL Convenience trim
  • "AWD SE" — ICE, SE trim

Leave trims as an empty array to get all trims for a model.

Response Structure

{
  "data": {
    "items": [
      {
        "vin": "KM8RMESA0TU000001",
        "modelYear": 2026,
        "modelName": "Palisade",
        "trimName": "Calligraphy",
        "extColorName": "Abyss Black",
        "intColorName": "Black",
        "msrp": 61250,
        "drivetrain": "AWD",
        "dealerCode": "VA001",
        "distance": 7.2,
        "inventoryStatus": "A"
      }
    ],
    "total": 75,
    "page": 1,
    "pageSize": 30
  }
}

Pagination

The API caps pageSize at 30. Use data.total from the first response to determine how many pages to fetch:

const totalPages = Math.ceil(data.total / 30);

Important: XHR, Not Fetch

The Hyundai site itself calls this API via XMLHttpRequest, not the Fetch API. If you're intercepting network calls in the browser, make sure you're hooking XMLHttpRequest.prototype.open rather than window.fetch.


Dealer Locator

Endpoint

GET https://www.hyundaiusa.com/var/hyundai/services/dealer.dealerByZipV2.service

Query Parameters

model=all&zip=20036&distance=50&maxdealers=50

Response Structure

{
  "dealers": [
    {
      "dealerCode": "VA001",
      "dealerName": "Capital Hyundai",
      "city": "Alexandria",
      "state": "VA",
      "distance": 7.2
    }
  ]
}

Use dealerCode to join dealer city/state onto inventory results.


Window Sticker (Monroney PDF)

Endpoint

GET https://www.hyundaiusa.com/var/hyundai/services/inventory/monroney.pdf?model=Palisade+Hev&vin={VIN}

Notes

  • Requires authentication — this endpoint checks browser session cookies. Direct curl requests will return an HTML login page.
  • To fetch from a browser context (e.g., in the DevTools console or a content script), use fetch() which automatically carries session cookies:
const res = await fetch(
  `https://www.hyundaiusa.com/var/hyundai/services/inventory/monroney.pdf?model=Palisade+Hev&vin=${vin}`
);
const buffer = await res.arrayBuffer();
  • The model query param uses + for spaces and appends +Hev for hybrid models. For ICE models, omit +Hev.
  • PDFs contain real text layers (not scanned images), so text extraction via pdf.js works cleanly without OCR.

Example: Fetch All Inventory (Browser Console)

async function fetchAllInventory(zip, distance, modelCode, trimName) {
  const results = [];
  let page = 1;
  let total = Infinity;

  while ((page - 1) * 30 < total) {
    const res = await new Promise((resolve, reject) => {
      const xhr = new XMLHttpRequest();
      xhr.open('POST', 'https://papp-bsi-api.hyundaiusa.com/inventory/item/v2/search', true);
      xhr.setRequestHeader('Content-Type', 'application/json');
      xhr.setRequestHeader('Accept', 'application/json, text/plain, */*');
      xhr.onload = () => resolve(JSON.parse(xhr.responseText).data);
      xhr.onerror = reject;
      xhr.send(JSON.stringify({
        zipCode: zip,
        distance: distance,
        page: page,
        pageSize: 30,
        sort: { attributeName: 'distance', order: 'asc' },
        atDealershipOnly: false,
        availableOnline: false,
        filterTag: 'modelName',
        modelYear: [2026],
        modelName: [{ code: modelCode, trims: [{ name: trimName, packages: [] }] }]
      }));
    });

    total = res.total;
    results.push(...res.items);
    page++;
  }

  return results;
}

// Usage
const inventory = await fetchAllInventory('20036', 25, 'J006', 'HEV CALLIGRAPHY');
console.log(`Found ${inventory.length} vehicles`);

Discovered via browser network inspection. Last verified: February 2026.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment