> ## Documentation Index
> Fetch the complete documentation index at: https://docs.homeservicedata.org/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Home Service Data REST API Overview

> Reference for the Home Service Data REST API: base URL, authentication, response envelope, versioning, trades, endpoint groups, and trust metadata.

The Home Service Data REST API gives quoting tools, CRMs, and sales platforms programmatic access to structured, source-labeled data across five home-service trades. Every response is wrapped in a consistent envelope, every data row carries readiness signals, and the API is versioned so your integration stays stable as the dataset grows.

## Base URL

All API endpoints are served from a single base URL. The current stable version is `v1`.

```
https://homeservicedata.org/api/v1
```

<Note>
  Always use HTTPS. HTTP requests are not supported. Append endpoint paths directly to the base URL — for example, `https://homeservicedata.org/api/v1/search`.
</Note>

## Authentication

Every request must include your API key in the `x-api-key` request header. There are no bearer tokens or cookies — the header is the sole authentication mechanism.

```http theme={null}
GET /api/v1/search?q=Goodman HTTP/1.1
Host: homeservicedata.org
x-api-key: YOUR_API_KEY
```

API keys are organization-scoped. A key issued to your organization inherits the dataset entitlements that have been provisioned for that organization. Some keys carry additional per-key scope restrictions that cap access to a subset of those entitlements.

<Tip>
  Keep your API key out of client-side code and version control. Rotate it immediately if it is exposed. See the [Authentication](/docs/authentication) guide for key management details.
</Tip>

## Response Envelope

Every API response — whether successful or not — is wrapped in a standard three-field envelope.

```json theme={null}
{
  "data": [ ... ],
  "error": null,
  "meta": {
    "page": 1,
    "per_page": 25,
    "total": 142,
    "total_pages": 6,
    "request_id": "req_01J...",
    "api_version": "2026-06-30",
    "dataset_version": null,
    "trust": {
      "endpoint": "/api/v1/catalog/equipment",
      "level": "mixed",
      "use_case": "Browse entitled equipment records.",
      "data_rights_note": "Use records according to quote-safe and entitlement labels.",
      "required_response_fields": ["quote_safe", "source_url"]
    },
    "performance": {
      "target_ms": 300,
      "warn_ms": 600,
      "max_response_bytes": 131072,
      "basis": "server"
    }
  }
}
```

<ResponseField name="data" type="array | object | null">
  The payload returned by the endpoint. `null` on error responses.
</ResponseField>

<ResponseField name="error" type="string | null">
  A human-readable error message. `null` on success responses. See [Errors](/docs/api-reference/errors) for the full list of error codes and messages.
</ResponseField>

<ResponseField name="meta" type="object | null">
  Request metadata, versioning, trust metadata, performance budgets, and optional pagination, coverage, or sync context. Some low-level responses may omit fields that do not apply.

  <Expandable title="meta fields">
    <ResponseField name="meta.page" type="number">
      The current page number (1-indexed).
    </ResponseField>

    <ResponseField name="meta.per_page" type="number">
      The number of records returned per page.
    </ResponseField>

    <ResponseField name="meta.total" type="number">
      Total records matching the request filters.
    </ResponseField>

    <ResponseField name="meta.total_pages" type="number">
      Total pages at the current `per_page` size.
    </ResponseField>

    <ResponseField name="meta.request_id" type="string">
      Stable request identifier matching the `X-HSD-Request-Id` response header.
    </ResponseField>

    <ResponseField name="meta.api_version" type="string">
      Date-based API contract version matching the `X-HSD-API-Version` response header.
    </ResponseField>

    <ResponseField name="meta.dataset_version" type="string | null">
      Dataset version or cursor when the endpoint can attach one. `null` when the endpoint is not tied to a single dataset version.
    </ResponseField>

    <ResponseField name="meta.trust" type="object">
      Endpoint-level trust guidance: intended use, quote-safe/context level, data-rights note, and required fields to inspect.
    </ResponseField>

    <ResponseField name="meta.performance" type="object">
      Endpoint performance budget metadata: target duration, warning duration, response-size budget, and measurement basis.
    </ResponseField>
  </Expandable>
</ResponseField>

An error response looks like this:

```json theme={null}
{
  "data": null,
  "error": "Missing x-api-key header.",
  "meta": {
    "request_id": "req_01J...",
    "api_version": "2026-06-30",
    "dataset_version": null,
    "trust": {
      "endpoint": "/api/v1/search",
      "level": "mixed",
      "use_case": "Search across entitled datasets.",
      "data_rights_note": "Use result-level quote-safe labels before quoting.",
      "required_response_fields": ["quote_safe"]
    },
    "performance": {
      "target_ms": 300,
      "warn_ms": 600,
      "max_response_bytes": 65536,
      "basis": "server"
    }
  }
}
```

## Pagination

List endpoints accept `page` and `per_page` query parameters. The default is `page=1` and `per_page=25`. The maximum `per_page` is `100`.

```http theme={null}
GET /api/v1/catalog/equipment?trade=hvac&page=2&per_page=50
```

Iterate through pages by incrementing `page` until `page` exceeds `meta.total_pages`.

## Data Quality Signals

Every data row that can be used in a quote carries at least two readiness signals. These are not decorative — they drive which records are safe to surface to customers.

<CardGroup cols={2}>
  <Card title="quote_safe" icon="shield-check">
    `true` when the record has passed all validation checks and is approved for use in customer-facing quotes. Always filter on `quote_safe=true` in production quote flows.
  </Card>

  <Card title="confidence" icon="chart-bar">
    A three-tier signal — `high`, `medium`, or `low` — indicating how closely the data matches a primary source. Higher confidence means fewer assumptions.
  </Card>

  <Card title="last_verified_at" icon="clock">
    ISO 8601 timestamp of the most recent source verification. Stale records may still be `quote_safe` but their `confidence` will reflect the age.
  </Card>

  <Card title="source_url" icon="link">
    The canonical URL of the original source document or data sheet, where available. Useful for audit trails and compliance review.
  </Card>
</CardGroup>

## Supported Trades

The API is organized around trade verticals. Pass the `trade` parameter to scope results to a single vertical.

| Trade      | `trade` value |
| ---------- | ------------- |
| Solar      | `solar`       |
| HVAC       | `hvac`        |
| Roofing    | `roofing`     |
| Plumbing   | `plumbing`    |
| Electrical | `electrical`  |

Some endpoints (utility territory, climate, permits) serve cross-trade context data. Those records carry `trade: "context"` in their responses.

## Versioning

The API uses URL-path versioning. The current version is **v1**. Breaking changes will be released under a new version prefix (`/api/v2/…`) with a documented migration period. Non-breaking additions — new fields, new optional parameters, new endpoint groups — may be added to v1 without a version bump.

## Endpoint Groups

<CardGroup cols={2}>
  <Card title="Finance" icon="credit-card" href="/docs/api-reference/finance-fees">
    Dealer fee programs, interest rates, term structures, and lender integrations. Requires `finance_fees` production access.
  </Card>

  <Card title="Equipment / Hardware" icon="cpu" href="/docs/api-reference/catalog-equipment">
    The full equipment catalog: solar modules, inverters, HVAC systems, roofing products, and generic hardware. Paginated browsing with category, manufacturer, and SKU filters.
  </Card>

  <Card title="Context" icon="map-pin">
    Location-aware context data — utility territories, electricity rates, incentive programs, permit assumptions, climate zones, and labor adders. Feed address-level data into quotes.
  </Card>

  <Card title="Sync" icon="refresh-cw">
    Dataset snapshots for bulk integration. Pull versioned exports of any entitled dataset into your own data store for offline use.
  </Card>

  <Card title="Search" icon="search" href="/docs/api-reference/search">
    Unified full-text search across all dataset types — equipment, finance programs, incentives, utilities, permits, labor, and source documents — in a single request.
  </Card>

  <Card title="Benchmarks" icon="bar-chart-2">
    Statistical aggregates (average, median, P25/P75, std dev) for pricing and performance metrics, filterable by trade, region, and time window.
  </Card>

  <Card title="Quote Context" icon="file-text">
    A single composite endpoint that assembles all quote-ready context for a given address and trade: equipment options, finance programs, incentives, utility rates, and permit requirements — deduplicated and `quote_safe` filtered.
  </Card>
</CardGroup>

## Response Timing Headers

Every response includes `X-HSD-Request-Id`, `X-HSD-API-Version`, `X-HSD-Duration-Ms`, and `X-HSD-Performance-State` headers. Most API responses also include a `Server-Timing` header with per-phase breakdowns such as auth, database, access checks, and route-specific work. These are useful for diagnosing latency and correlating support logs in production integrations.

## Further Reading

* [Authentication](/docs/authentication) — API key management, scopes, and rotation
* [Error Codes](/docs/api-reference/errors) — HTTP status codes, error messages, and retry strategy
