# The HeatCheck API

> Public market endpoints need no key; an [Investor](https://heatcheck.tech/pricing) API key opens every venue, market, compare and report endpoint.

## Overview

- **Base URL:** `https://api.heatcheck.tech`
- **Format:** JSON (UTF-8); CSV for report downloads
- **Versions:** In the path (`/v1`, `/public/v1`); `/health`, `/public/pulse` and `/public/heatmap` are unversioned
- **Dates:** New York local `YYYY-MM-DD`; instants in UTC ISO 8601
- **Period:** `grain` (`day`, the default, or `month`), `from` and `to` (inclusive dates, not before 2026-10-24; `to` defaults to yesterday). At most 92 days or 24 months.
- **Money:** Integer USD cents (`6500` = $65.00)
- **Unknown:** `null`, never `0`
- **Examples:** Illustrative values, long arrays trimmed
- **Estimates:** `low` (P10), `mid` (P50 for revenue, the mean otherwise), `high` (P90), `ci: 0.8`, an A–D `grade`, `drivers`

## Authentication

- [Investor](https://heatcheck.tech/pricing) owners and admins create keys under Account → API keys, up to 5 per account. A key looks like `hc_live_<8-character prefix>_<32-character secret>`, is shown once and is stored only as a SHA-256 hash; revoking it is immediate.
- Keys reach `/v1/*` only. A missing, unknown or revoked key is `401 invalid_api_key`; an account no longer on Investor gets `403 plan_required`. With an `Authorization` header, cookies are ignored.
- Public endpoints need no key and allow any origin (CORS, without credentials).

```sh
export HEATCHECK_API_KEY="hc_live_…"
curl -H "Authorization: Bearer $HEATCHECK_API_KEY" "https://api.heatcheck.tech/v1/venues"
```

## Endpoints

| Endpoint | Returns | Access |
|---|---|---|
| `GET /public/v1/markets` | Markets with public insights | Public, no key |
| `GET /public/v1/markets/nyc/insights` | Weekly market insights | Public, no key |
| `GET /public/heatmap` | Weekday × half-hour market heatmap | Public, no key |
| `GET /public/pulse` | Live counts across every market | Public, no key |
| `GET /health` | Service status | Public, no key |
| `GET /v1/venues` | Every venue with its figures | Investor API key |
| `GET /v1/venues/{id}` | One venue in full | Investor API key |
| `GET /v1/venues/{id}/timeline` | Contraction timeline of one date | Investor API key |
| `GET /v1/compare` | 2–6 venues side by side | Investor API key |
| `GET /v1/market` | Market and borough totals | Investor API key |
| `POST /v1/reports` | A new CSV report | Investor API key |
| `GET /v1/reports` | Your account’s reports | Investor API key |
| `GET /v1/reports/{id}/download` | The CSV file | Investor API key |

### GET /public/v1/markets

The 17 markets with insights and a heatmap (at least 3 public venues), deepest first, with venue counts and the latest completed ISO week.

Access: public, no key.

```sh
curl "https://api.heatcheck.tech/public/v1/markets"
```

Example response, values illustrative:

```json
{
  "markets": [
    {
      "id": "nyc",
      "name": "New York City",
      "venues": 27,
      "latestWeek": {
        "id": "2026-W45",
        "from": "2026-11-02",
        "to": "2026-11-08"
      }
    },
    {
      "id": "orange-county",
      "name": "Orange County, CA",
      "venues": 11,
      "latestWeek": {
        "id": "2026-W45",
        "from": "2026-11-02",
        "to": "2026-11-08"
      }
    }
  ]
}
```

### GET /public/v1/markets/nyc/insights

The data of the [insights pages](https://heatcheck.tech/insights): one completed week of market utilization, weekdays, weekday × daypart cells, peaks, borough bands (New York City only) and a trend of up to 13 weeks. No venue names or money; under 3 contributing venues is `null`. `ref` identifies the request. CC BY 4.0, credit “HeatCheck (heatcheck.tech)”.

Access: public, no key.

- `market` (path, required): Market id from `/public/v1/markets` (`nyc`, `orange-county`, `los-angeles`, …); others are `404 market_not_found`.
- `week` (query): ISO week `YYYY-Www`, one of the last 13 completed, never earlier than `2026-W44`. Defaults to the latest; others are `404 week_not_public`.

```sh
curl "https://api.heatcheck.tech/public/v1/markets/nyc/insights?week=2026-W45"
```

Example response, values illustrative:

```json
{
  "market": {
    "id": "nyc",
    "name": "New York City"
  },
  "week": {
    "id": "2026-W45",
    "from": "2026-11-02",
    "to": "2026-11-08"
  },
  "computedAt": "2026-11-09T09:00:00.000Z",
  "methodVersion": "public-insights/v1",
  "venues": 27,
  "observedVenues": 19,
  "utilization": 0.64,
  "changePoints": 3,
  "weekdays": [
    {
      "weekday": "MON",
      "utilization": 0.52
    },
    {
      "weekday": "SAT",
      "utilization": 0.78
    }
  ],
  "dayparts": {
    "rows": [
      "MON",
      "SAT"
    ],
    "cols": [
      "early",
      "morning",
      "midday",
      "afternoon",
      "evening",
      "late"
    ],
    "cells": [
      [
        null,
        0.41,
        0.47,
        0.5,
        0.68,
        0.55
      ],
      [
        0.36,
        0.7,
        0.79,
        0.76,
        0.81,
        0.63
      ]
    ]
  },
  "peaks": {
    "busiest": [
      {
        "weekday": "SAT",
        "daypart": "evening",
        "utilization": 0.81
      }
    ],
    "quietest": [
      {
        "weekday": "MON",
        "daypart": "morning",
        "utilization": 0.41
      }
    ]
  },
  "boroughs": [
    {
      "borough": "Manhattan",
      "venues": 11,
      "utilization": {
        "low": 0.6,
        "high": 0.7
      }
    },
    {
      "borough": "Staten Island",
      "venues": 1,
      "utilization": null
    }
  ],
  "trend": [
    {
      "week": "2026-W44",
      "from": "2026-10-26",
      "utilization": 0.61
    },
    {
      "week": "2026-W45",
      "from": "2026-11-02",
      "utilization": 0.64
    }
  ],
  "license": "CC BY 4.0",
  "attribution": "HeatCheck (heatcheck.tech)",
  "links": {
    "self": "https://api.heatcheck.tech/public/v1/markets/nyc/insights?week=2026-W45",
    "html": "https://heatcheck.tech/insights/nyc/2026-w45",
    "methodology": "https://heatcheck.tech/methodology",
    "pricing": "https://heatcheck.tech/pricing",
    "previous": "https://api.heatcheck.tech/public/v1/markets/nyc/insights?week=2026-W44",
    "next": null
  },
  "ref": "r_3f9c2a7b"
}
```

### GET /public/heatmap

One market’s last completed week: seven weekdays × half-hour starts (00:00–23:30), each cell the unit-hour-weighted utilization of completed slots. Fewer than 3 contributing venues is `null`; `offered` tells unknown from not offered.

Access: public, no key.

- `market` (query): Market id from `/public/v1/markets`; default `nyc`. Others are `404 market_not_found`.

```sh
curl "https://api.heatcheck.tech/public/heatmap?market=nyc"
```

Example response, values illustrative:

```json
{
  "period": {
    "grain": "day",
    "from": "2026-10-26",
    "to": "2026-11-01"
  },
  "computedAt": "2026-11-02T09:00:00.000Z",
  "venues": 27,
  "methodVersion": "public-heatmap/v1",
  "heatmap": {
    "rows": [
      "Mon",
      "Tue"
    ],
    "cols": [
      "18:00",
      "18:30"
    ],
    "cells": [
      [
        0.71,
        null
      ],
      [
        0.66,
        0.58
      ]
    ],
    "offered": [
      [
        true,
        true
      ],
      [
        true,
        true
      ]
    ]
  }
}
```

### GET /public/pulse

Live counts across every public market, yesterday’s utilization and one anonymous heat point per venue (`heat: null` without supply).

Access: public, no key.

```sh
curl "https://api.heatcheck.tech/public/pulse"
```

Example response, values illustrative:

```json
{
  "venues": 127,
  "slotsTracked": 1840,
  "pollsPerDay": 5904,
  "yesterday": {
    "date": "2026-11-01",
    "utilization": 0.6412,
    "soldUnits": 1312
  },
  "points": [
    {
      "lat": 40.7411,
      "lng": -73.9897,
      "heat": 0.7
    },
    {
      "lat": 40.6782,
      "lng": -73.9442,
      "heat": null
    }
  ]
}
```

### GET /health

`200` with the version while the service and database are up; `503` with `status: "error"` otherwise.

Access: public, no key.

```sh
curl "https://api.heatcheck.tech/health"
```

Example response, values illustrative:

```json
{
  "status": "ok",
  "version": "0.1.0"
}
```

### GET /v1/venues

Every public venue with its figures for the period and `spark`, its daily utilization.

Access: Investor API key.

- `grain, from, to` (query): The period (see Overview).

```sh
curl -H "Authorization: Bearer $HEATCHECK_API_KEY" "https://api.heatcheck.tech/v1/venues?from=2026-10-26&to=2026-11-01"
```

Example response, values illustrative:

```json
{
  "period": {
    "grain": "day",
    "from": "2026-10-26",
    "to": "2026-11-01"
  },
  "access": {
    "plan": "investor",
    "resolution": "exact",
    "window": null,
    "locked": []
  },
  "venues": [
    {
      "venue": {
        "id": "example-bathhouse",
        "name": "Example Bathhouse",
        "brand": "Example",
        "neighborhood": "Flatiron",
        "borough": "Manhattan",
        "lat": 40.7411,
        "lng": -73.9897,
        "unitLabel": "admission",
        "unitsLabel": "admissions",
        "platform": "trybe",
        "studied": [
          "Bathhouse day pass"
        ],
        "listPrice": {
          "minor": 6500,
          "per": "admission",
          "source": "pricing-page"
        }
      },
      "figures": {
        "venueId": "example-bathhouse",
        "period": {
          "grain": "day",
          "from": "2026-11-01",
          "to": "2026-11-01",
          "label": "2026-11-01"
        },
        "status": "complete",
        "slots": {
          "offered": 30,
          "completed": 30,
          "stale": 0,
          "open": 0
        },
        "supply": {
          "units": 600,
          "unitHours": 1200
        },
        "sold": {
          "low": 402,
          "mid": 418,
          "high": 431,
          "ci": 0.8,
          "grade": "A",
          "drivers": [
            {
              "factor": "stale-final-states",
              "share": 1
            }
          ]
        },
        "utilization": {
          "low": 0.67,
          "mid": 0.697,
          "high": 0.718,
          "ci": 0.8,
          "grade": "A",
          "drivers": [
            {
              "factor": "stale-final-states",
              "share": 1
            }
          ]
        },
        "coverage": 0.98,
        "leftCensoredUnits": 12,
        "revenue": {
          "low": 2540000,
          "mid": 2790000,
          "high": 3080000,
          "ci": 0.8,
          "grade": "B",
          "drivers": [
            {
              "factor": "mix-price",
              "share": 0.58
            },
            {
              "factor": "sold-share",
              "share": 0.42
            }
          ]
        },
        "revPAUH": {
          "low": 181000,
          "mid": 199000,
          "high": 220000,
          "ci": 0.8,
          "grade": "B",
          "drivers": [
            {
              "factor": "mix-price",
              "share": 0.58
            },
            {
              "factor": "sold-share",
              "share": 0.42
            }
          ]
        },
        "guests": null,
        "price": {
          "minMinor": 5500,
          "medianMinor": 6500,
          "maxMinor": 9500
        },
        "modelVersions": {
          "utilization": "utilization/v1",
          "revenue": "revenue/v3"
        },
        "model": {
          "utilization": "v2",
          "revenue": "v3"
        }
      },
      "spark": [
        0.66,
        0.71,
        0.697
      ]
    }
  ]
}
```

### GET /v1/venues/{id}

Profile, figures, a `series` row per day or month, the start-time heatmap (with `sold` and `capacity`) and the next-day forecast.

Access: Investor API key.

- `id` (path, required): Venue id from `/v1/venues`.
- `grain, from, to` (query): The period (see Overview).

```sh
curl -H "Authorization: Bearer $HEATCHECK_API_KEY" "https://api.heatcheck.tech/v1/venues/example-bathhouse?from=2026-11-01&to=2026-11-01"
```

Example response, values illustrative:

```json
{
  "period": {
    "grain": "day",
    "from": "2026-11-01",
    "to": "2026-11-01"
  },
  "access": {
    "plan": "investor",
    "resolution": "exact",
    "window": null,
    "locked": []
  },
  "venue": {
    "id": "example-bathhouse",
    "name": "Example Bathhouse",
    "brand": "Example",
    "neighborhood": "Flatiron",
    "borough": "Manhattan",
    "lat": 40.7411,
    "lng": -73.9897,
    "unitLabel": "admission",
    "unitsLabel": "admissions",
    "platform": "trybe",
    "studied": [
      "Bathhouse day pass"
    ],
    "listPrice": {
      "minor": 6500,
      "per": "admission",
      "source": "pricing-page"
    },
    "description": "Thermal circuit with saunas, steam rooms and cold plunges",
    "address": {
      "line1": "1 Example Street",
      "city": "New York",
      "region": "NY",
      "postalCode": "10010"
    },
    "website": "https://example.com",
    "bookingUrl": "https://example.com/book",
    "services": [
      {
        "id": "day-pass",
        "name": "Bathhouse day pass",
        "category": "thermal-circuit",
        "prices": [
          {
            "amountMinor": 6500,
            "currency": "USD",
            "per": "person",
            "durationMinutes": 120,
            "source": "pricing-page",
            "observedAt": "2026-10-24"
          }
        ],
        "studied": true,
        "source": "pricing-page"
      }
    ],
    "scope": {
      "unit": "admission",
      "window": "30-minute arrival window",
      "notes": [
        "Day passes only"
      ],
      "excluded": [
        {
          "what": "Spa treatments",
          "why": "Booked by appointment, not by arrival window"
        }
      ]
    },
    "pools": [
      {
        "id": "admission",
        "label": "Day pass entry",
        "kind": "entry-window"
      }
    ],
    "streams": [
      {
        "id": "near",
        "cadenceMinutes": 5,
        "dayOffsets": [
          0,
          2
        ]
      }
    ]
  },
  "figures": {
    "venueId": "example-bathhouse",
    "period": {
      "grain": "day",
      "from": "2026-11-01",
      "to": "2026-11-01",
      "label": "2026-11-01"
    },
    "status": "complete",
    "slots": {
      "offered": 30,
      "completed": 30,
      "stale": 0,
      "open": 0
    },
    "supply": {
      "units": 600,
      "unitHours": 1200
    },
    "sold": {
      "low": 402,
      "mid": 418,
      "high": 431,
      "ci": 0.8,
      "grade": "A",
      "drivers": [
        {
          "factor": "stale-final-states",
          "share": 1
        }
      ]
    },
    "utilization": {
      "low": 0.67,
      "mid": 0.697,
      "high": 0.718,
      "ci": 0.8,
      "grade": "A",
      "drivers": [
        {
          "factor": "stale-final-states",
          "share": 1
        }
      ]
    },
    "coverage": 0.98,
    "leftCensoredUnits": 12,
    "revenue": {
      "low": 2540000,
      "mid": 2790000,
      "high": 3080000,
      "ci": 0.8,
      "grade": "B",
      "drivers": [
        {
          "factor": "mix-price",
          "share": 0.58
        },
        {
          "factor": "sold-share",
          "share": 0.42
        }
      ]
    },
    "revPAUH": {
      "low": 181000,
      "mid": 199000,
      "high": 220000,
      "ci": 0.8,
      "grade": "B",
      "drivers": [
        {
          "factor": "mix-price",
          "share": 0.58
        },
        {
          "factor": "sold-share",
          "share": 0.42
        }
      ]
    },
    "guests": null,
    "price": {
      "minMinor": 5500,
      "medianMinor": 6500,
      "maxMinor": 9500
    },
    "modelVersions": {
      "utilization": "utilization/v1",
      "revenue": "revenue/v3"
    },
    "model": {
      "utilization": "v2",
      "revenue": "v3"
    }
  },
  "series": [
    {
      "venueId": "example-bathhouse",
      "period": {
        "grain": "day",
        "from": "2026-11-01",
        "to": "2026-11-01",
        "label": "2026-11-01"
      },
      "status": "complete",
      "slots": {
        "offered": 30,
        "completed": 30,
        "stale": 0,
        "open": 0
      },
      "supply": {
        "units": 600,
        "unitHours": 1200
      },
      "sold": {
        "low": 402,
        "mid": 418,
        "high": 431,
        "ci": 0.8,
        "grade": "A",
        "drivers": [
          {
            "factor": "stale-final-states",
            "share": 1
          }
        ]
      },
      "utilization": {
        "low": 0.67,
        "mid": 0.697,
        "high": 0.718,
        "ci": 0.8,
        "grade": "A",
        "drivers": [
          {
            "factor": "stale-final-states",
            "share": 1
          }
        ]
      },
      "coverage": 0.98,
      "leftCensoredUnits": 12,
      "revenue": {
        "low": 2540000,
        "mid": 2790000,
        "high": 3080000,
        "ci": 0.8,
        "grade": "B",
        "drivers": [
          {
            "factor": "mix-price",
            "share": 0.58
          },
          {
            "factor": "sold-share",
            "share": 0.42
          }
        ]
      },
      "revPAUH": {
        "low": 181000,
        "mid": 199000,
        "high": 220000,
        "ci": 0.8,
        "grade": "B",
        "drivers": [
          {
            "factor": "mix-price",
            "share": 0.58
          },
          {
            "factor": "sold-share",
            "share": 0.42
          }
        ]
      },
      "guests": null,
      "price": {
        "minMinor": 5500,
        "medianMinor": 6500,
        "maxMinor": 9500
      },
      "modelVersions": {
        "utilization": "utilization/v1",
        "revenue": "revenue/v3"
      },
      "model": {
        "utilization": "v2",
        "revenue": "v3"
      }
    }
  ],
  "heatmap": {
    "rows": [
      "2026-11-01"
    ],
    "cols": [
      "18:00",
      "18:30"
    ],
    "cells": [
      [
        0.93,
        null
      ]
    ],
    "offered": [
      [
        true,
        true
      ]
    ],
    "sold": [
      [
        28,
        null
      ]
    ],
    "capacity": [
      [
        30,
        null
      ]
    ]
  },
  "forecast": {
    "venueId": "example-bathhouse",
    "date": "2026-11-02",
    "asOf": "2026-11-01T22:00:00.000Z",
    "status": "provisional",
    "method": "additive-pickup-v1",
    "bookedSoFar": {
      "units": 212,
      "share": 0.35
    },
    "sold": {
      "low": 371,
      "mid": 405,
      "high": 438,
      "ci": 0.8,
      "grade": "B",
      "drivers": []
    },
    "revenue": {
      "low": 2330000,
      "mid": 2640000,
      "high": 2990000,
      "ci": 0.8,
      "grade": "B",
      "drivers": []
    },
    "utilization": {
      "low": 0.62,
      "mid": 0.675,
      "high": 0.73,
      "ci": 0.8,
      "grade": "B",
      "drivers": []
    },
    "reason": null
  }
}
```

### GET /v1/venues/{id}/timeline

How each slot of one service date sold down, poll by poll, and the booking pace curve. `leftCensored` counts units already gone at the first observation.

Access: Investor API key.

- `id` (path, required): Venue id.
- `date` (query): Service date `YYYY-MM-DD`; defaults to yesterday on Pro, today on Investor (New York). On Pro, today or later is `403 plan_required` (`intraday`).

```sh
curl -H "Authorization: Bearer $HEATCHECK_API_KEY" "https://api.heatcheck.tech/v1/venues/example-bathhouse/timeline?date=2026-11-01"
```

Example response, values illustrative:

```json
{
  "date": "2026-11-01",
  "slots": [
    {
      "time": "18:00",
      "poolId": "admission",
      "capacity": 30,
      "leftCensored": 6,
      "points": [
        {
          "at": "2026-10-30T22:00:00.000Z",
          "unavailable": 6
        },
        {
          "at": "2026-11-01T22:55:00.000Z",
          "unavailable": 28
        }
      ],
      "finalStatus": "completed"
    }
  ],
  "curve": [
    {
      "leadHours": 48,
      "share": 0.21
    },
    {
      "leadHours": 0,
      "share": 0.83
    }
  ],
  "access": {
    "plan": "investor",
    "resolution": "exact",
    "window": null,
    "locked": []
  }
}
```

### GET /v1/compare

Figures and series of 2–6 venues on one period and scale. An unknown id is `404 venue_not_found`.

Access: Investor API key.

- `ids` (query, required): Comma-separated venue ids, 2 to 6.
- `grain, from, to` (query): The period (see Overview).

```sh
curl -H "Authorization: Bearer $HEATCHECK_API_KEY" "https://api.heatcheck.tech/v1/compare?ids=example-bathhouse,another-venue&from=2026-11-01&to=2026-11-01"
```

Example response, values illustrative:

```json
{
  "period": {
    "grain": "day",
    "from": "2026-11-01",
    "to": "2026-11-01"
  },
  "access": {
    "plan": "investor",
    "resolution": "exact",
    "window": null,
    "locked": []
  },
  "venues": [
    {
      "venue": {
        "id": "example-bathhouse",
        "name": "Example Bathhouse",
        "brand": "Example",
        "neighborhood": "Flatiron",
        "borough": "Manhattan",
        "lat": 40.7411,
        "lng": -73.9897,
        "unitLabel": "admission",
        "unitsLabel": "admissions",
        "platform": "trybe",
        "studied": [
          "Bathhouse day pass"
        ],
        "listPrice": {
          "minor": 6500,
          "per": "admission",
          "source": "pricing-page"
        }
      },
      "figures": {
        "venueId": "example-bathhouse",
        "period": {
          "grain": "day",
          "from": "2026-11-01",
          "to": "2026-11-01",
          "label": "2026-11-01"
        },
        "status": "complete",
        "slots": {
          "offered": 30,
          "completed": 30,
          "stale": 0,
          "open": 0
        },
        "supply": {
          "units": 600,
          "unitHours": 1200
        },
        "sold": {
          "low": 402,
          "mid": 418,
          "high": 431,
          "ci": 0.8,
          "grade": "A",
          "drivers": [
            {
              "factor": "stale-final-states",
              "share": 1
            }
          ]
        },
        "utilization": {
          "low": 0.67,
          "mid": 0.697,
          "high": 0.718,
          "ci": 0.8,
          "grade": "A",
          "drivers": [
            {
              "factor": "stale-final-states",
              "share": 1
            }
          ]
        },
        "coverage": 0.98,
        "leftCensoredUnits": 12,
        "revenue": {
          "low": 2540000,
          "mid": 2790000,
          "high": 3080000,
          "ci": 0.8,
          "grade": "B",
          "drivers": [
            {
              "factor": "mix-price",
              "share": 0.58
            },
            {
              "factor": "sold-share",
              "share": 0.42
            }
          ]
        },
        "revPAUH": {
          "low": 181000,
          "mid": 199000,
          "high": 220000,
          "ci": 0.8,
          "grade": "B",
          "drivers": [
            {
              "factor": "mix-price",
              "share": 0.58
            },
            {
              "factor": "sold-share",
              "share": 0.42
            }
          ]
        },
        "guests": null,
        "price": {
          "minMinor": 5500,
          "medianMinor": 6500,
          "maxMinor": 9500
        },
        "modelVersions": {
          "utilization": "utilization/v1",
          "revenue": "revenue/v3"
        },
        "model": {
          "utilization": "v2",
          "revenue": "v3"
        }
      },
      "series": [
        {
          "venueId": "example-bathhouse",
          "period": {
            "grain": "day",
            "from": "2026-11-01",
            "to": "2026-11-01",
            "label": "2026-11-01"
          },
          "status": "complete",
          "slots": {
            "offered": 30,
            "completed": 30,
            "stale": 0,
            "open": 0
          },
          "supply": {
            "units": 600,
            "unitHours": 1200
          },
          "sold": {
            "low": 402,
            "mid": 418,
            "high": 431,
            "ci": 0.8,
            "grade": "A",
            "drivers": [
              {
                "factor": "stale-final-states",
                "share": 1
              }
            ]
          },
          "utilization": {
            "low": 0.67,
            "mid": 0.697,
            "high": 0.718,
            "ci": 0.8,
            "grade": "A",
            "drivers": [
              {
                "factor": "stale-final-states",
                "share": 1
              }
            ]
          },
          "coverage": 0.98,
          "leftCensoredUnits": 12,
          "revenue": {
            "low": 2540000,
            "mid": 2790000,
            "high": 3080000,
            "ci": 0.8,
            "grade": "B",
            "drivers": [
              {
                "factor": "mix-price",
                "share": 0.58
              },
              {
                "factor": "sold-share",
                "share": 0.42
              }
            ]
          },
          "revPAUH": {
            "low": 181000,
            "mid": 199000,
            "high": 220000,
            "ci": 0.8,
            "grade": "B",
            "drivers": [
              {
                "factor": "mix-price",
                "share": 0.58
              },
              {
                "factor": "sold-share",
                "share": 0.42
              }
            ]
          },
          "guests": null,
          "price": {
            "minMinor": 5500,
            "medianMinor": 6500,
            "maxMinor": 9500
          },
          "modelVersions": {
            "utilization": "utilization/v1",
            "revenue": "revenue/v3"
          },
          "model": {
            "utilization": "v2",
            "revenue": "v3"
          }
        }
      ]
    }
  ]
}
```

### GET /v1/market

Market and borough revenue (the sum of venue estimates), unit-hour-weighted utilization and coverage. An estimate with nothing behind it is `null`, never zero.

Access: Investor API key.

- `grain, from, to` (query): The period (see Overview).

```sh
curl -H "Authorization: Bearer $HEATCHECK_API_KEY" "https://api.heatcheck.tech/v1/market?from=2026-10-26&to=2026-11-01"
```

Example response, values illustrative:

```json
{
  "period": {
    "grain": "day",
    "from": "2026-10-26",
    "to": "2026-11-01"
  },
  "access": {
    "plan": "investor",
    "resolution": "exact",
    "window": null,
    "locked": []
  },
  "figures": {
    "revenue": {
      "low": 41200000,
      "mid": 48900000,
      "high": 58100000,
      "ci": 0.8,
      "grade": "B",
      "drivers": []
    },
    "utilization": {
      "low": 0.61,
      "mid": 0.64,
      "high": 0.67,
      "ci": 0.8,
      "grade": "A",
      "drivers": []
    },
    "coverage": {
      "venues": 27,
      "observed": 19
    }
  },
  "byBorough": [
    {
      "borough": "Manhattan",
      "revenue": {
        "low": 25800000,
        "mid": 31400000,
        "high": 38000000,
        "ci": 0.8,
        "grade": "B",
        "drivers": []
      },
      "utilization": {
        "low": 0.63,
        "mid": 0.66,
        "high": 0.69,
        "ci": 0.8,
        "grade": "A",
        "drivers": []
      },
      "coverage": {
        "venues": 11,
        "observed": 11
      }
    }
  ]
}
```

### POST /v1/reports

Builds a CSV: `venue`, `compare` (2–12 venues) or `market`, by default the 30 days to yesterday. Up to 20 a day per user; the same request on the same day returns the existing report (`200`, `reused: true`), for 15 minutes only if it reaches today. Kept 7 days.

Access: Investor API key.

- `kind` (body, required): `venue`, `compare` or `market`.
- `venueIds` (body): One for `venue`, 2–12 for `compare`, none for `market`.
- `grain, from, to` (body): The period, never clamped: a `day` range over 92 days is `400 period_too_long`.

```sh
curl -X POST -H "Authorization: Bearer $HEATCHECK_API_KEY" -H "Content-Type: application/json" \
  -d '{"kind":"market","grain":"day","from":"2026-10-24","to":"2026-11-01"}' \
  "https://api.heatcheck.tech/v1/reports"
```

Example response (201), values illustrative:

```json
{
  "report": {
    "id": "rpt_8d1f0c",
    "kind": "market",
    "label": "Market",
    "grain": "day",
    "from": "2026-10-24",
    "to": "2026-11-01",
    "venueIds": [],
    "status": "ready",
    "bytes": 18342,
    "createdAt": "2026-11-02T14:03:11.000Z",
    "expiresAt": "2026-11-09T14:03:11.000Z"
  }
}
```

### GET /v1/reports

Your accounts’ reports, newest first (up to 100), and today’s quota.

Access: Investor API key.

```sh
curl -H "Authorization: Bearer $HEATCHECK_API_KEY" "https://api.heatcheck.tech/v1/reports"
```

Example response, values illustrative:

```json
{
  "reports": [
    {
      "id": "rpt_8d1f0c",
      "kind": "market",
      "label": "Market",
      "grain": "day",
      "from": "2026-10-24",
      "to": "2026-11-01",
      "venueIds": [],
      "status": "ready",
      "bytes": 18342,
      "createdAt": "2026-11-02T14:03:11.000Z",
      "expiresAt": "2026-11-09T14:03:11.000Z"
    }
  ],
  "quota": {
    "used": 1,
    "limit": 20
  }
}
```

### GET /v1/reports/{id}/download

The report as `text/csv` (UTF-8 with BOM, CRLF), named `heatcheck-<kind>-<from>-<to>.csv`. Money in USD with cents; unknown values empty, never 0. Expired: `410 report_expired`.

Access: Investor API key.

- `id` (path, required): Report id from `/v1/reports`.

```sh
curl -H "Authorization: Bearer $HEATCHECK_API_KEY" -OJ "https://api.heatcheck.tech/v1/reports/rpt_8d1f0c/download"
```

Example response, values illustrative:

```csv
venue_id,name,period_from,period_to,status,supply_units,sold_low,sold_mid,sold_high,utilization_low,utilization_mid,utilization_high,revenue_low,revenue_mid,revenue_high,revpauh_mid,price_min,price_median,price_max,coverage,grade
```

## Rate limits

| Caller | Counted | Per day | Per minute |
|---|---|---|---|
| Anonymous, public routes | per IP (an IPv6 /48 counts as one) | 1,000 | 60 |
| Free, signed in | per user | 300 | — |
| Pro, signed in | per user | 3,000 | — |
| Investor, signed in | per user | 10,000 | — |
| Investor API key | per account a day, per key a minute | 10,000 | 60 |
| Investor CSV reports | new reports per user | 20 | — |

Days are New York days. `/v1` responses carry `RateLimit-Limit`, `RateLimit-Remaining` and `RateLimit-Reset` (seconds) for the daily quota. Over a limit: `429` with `Retry-After` (seconds).

## Plans and access

| Route | Free | Pro | Investor |
|---|---|---|---|
| `GET /v1/venues`, `/v1/venues/{id}`, `/v1/market` | Band shapes, last completed week | Full shapes, every day since 2026-10-24 | Same as Pro |
| `GET /v1/venues/{id}/timeline` | `plan_required` | ✓ | ✓ |
| `GET /v1/compare` | `plan_required` | ✓ (2–6 venues) | ✓ (2–6 venues) |
| `POST /v1/reports`, `GET /v1/reports`, download | `plan_required` | `plan_required` | ✓ (20 a day, up to 12 venues) |
| API keys on `/v1/*` | — | — | ✓ (5 keys) |

Free (signed in, no key): Always the last completed Monday–Sunday week. `/v1/venues` returns `{period, access, venues: [{venue, band}]}` by rank, each `band` a 10-point utilization band (`{low: 0.6, high: 0.7}`), `rank` and price range; `/v1/venues/{id}` adds `dayparts`; `/v1/market` returns bands and a revenue range rounded to two significant figures. No exact figure, series, revenue or half-hour cell.

## Errors

```json
{
  "error": {
    "code": "plan_required",
    "message": "Compare needs the Pro plan",
    "feature": "compare",
    "requiredPlan": "pro"
  }
}
```

| Status | Codes |
|---|---|
| 400 | `invalid_request`, `invalid_json`, `invalid_period`, `period_too_long`, `too_many_venues`, `invalid_week` |
| 401 | `invalid_api_key`, `unauthenticated` |
| 403 | `plan_required` (with `feature` and `requiredPlan`), `forbidden`, `no_account` |
| 404 | `not_found`, `venue_not_found`, `report_not_found`, `market_not_found`, `week_not_public` |
| 410 | `report_expired` |
| 415 | `unsupported_media_type`: a `POST` or `DELETE` without `Content-Type: application/json` |
| 429 | `quota_exceeded`, `rate_limited`, `report_quota_exceeded` |
| 503 | `busy` (retry shortly) |

## Licence

Public insights (the pages and `/public/v1`) are [CC BY 4.0](https://creativecommons.org/licenses/by/4.0/): reuse them, commercially too, crediting “HeatCheck (heatcheck.tech)”.

App, `/v1` and CSV data are for the subscribing account’s internal use; redistribution needs a separate agreement ([talk to us](mailto:hello@heatcheck.tech?subject=HeatCheck%20Investor)).

## Links

- [OpenAPI 3.1 description](https://heatcheck.tech/openapi.json)
- [llms.txt](https://heatcheck.tech/llms.txt)
- [Pricing](https://heatcheck.tech/pricing)
- [Methodology](https://heatcheck.tech/methodology)
- [Talk to us about Investor](mailto:hello@heatcheck.tech?subject=HeatCheck%20Investor)

---

HeatCheck — The first market intelligence platform for saunas and bathhouses. Canonical page: https://heatcheck.tech/developers · Contact: hello@heatcheck.tech · Index for agents: https://heatcheck.tech/llms.txt · Updated 2026-11-03
