Skip to content

HVAC API documentation

Authentication, the five MCP tools, their REST endpoints, three worked examples, error codes and sandbox limits. Contract version ar-00/1.

Authentication

Send an API key as a Bearer token on every request. Create and revoke keys in the developer area of the WebApp dashboard. Keys belong to your company, and the monthly allowance is shared across the company's keys.

Authorization: Bearer YOUR_API_KEY

The MCP server uses the same keys. Calls without a valid credential return 401 unauthorized before anything runs.

The five MCP tools

Each tool maps to one REST endpoint and returns the same JSON. Parameters are listed as the server defines them.

  • resolve_equipment

    Maps a nameplate reference to coverage. Not billed.

    Parameters
    reference (required), market = us, language = en-US
    REST
    POST /v1/equipment/resolve
  • search_hvac_documents

    Bounded passages with citations. operation_id replays a call without a second charge.

    Parameters
    question (required), brand, model_reference, fault_code, language = en-US, limit = 5, operation_id
    REST
    POST /v1/search
  • get_hvac_source

    The passage and its bounded context for a source you already have a citation for.

    Parameters
    source_id (required)
    REST
    GET /v1/sources/{source_id}
  • answer_hvac_question

    A written answer cited to manual passages. Separate from a summary your client writes itself.

    Parameters
    question (required), brand, model_reference, fault_code, language = en-US, limit = 5, operation_id
    REST
    POST /v1/answers
  • get_hvac_document_page

    The source page as a PNG image. With format pdf you also get a signed PDF link.

    Parameters
    document_version_id (required), page_number (required), format = png, region
    REST
    GET /v1/documents/{document_version_id}/pages/{page_number}

Also on REST: GET /v1/usage returns your allowance, usage and window end.

OpenAPI

The full schema is public. We link to it instead of copying it, so it is always the deployed version.

https://api.myleadtech.app/v1/openapi.json

Three examples

Responses below are examples from the ar-00/1 contract, shortened. They are not live captures.

1. Resolve a model

Turn a nameplate reference into brand and published documents. This call is free.

curl https://api.myleadtech.app/v1/equipment/resolve \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"reference":"27TPA8"}'
{
  "contract_version": "ar-00/1",
  "status": "covered",
  "usage": { "operation": "resolve_equipment", "debited": false },
  "coverage": "covered",
  "brand": "carrier",
  "published_documents": [
    { "document_type": "product_data", "title_hint": "27TPA8 Product Data" },
    { "document_type": "installation", "title_hint": "27TPA8 Installation Instructions" }
  ]
}

Carrier 27TPA8. Other statuses: family_only, not_covered, ambiguous.

2. Ask about a fault code

Pass fault_code with the question. When the library has no published fault-code facts for the unit, you get an abstention and no charge, not a guess.

curl https://api.myleadtech.app/v1/answers \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"question":"What does this fault code mean?",
       "model_reference":"YOUR_MODEL","fault_code":"YOUR_CODE"}'
{
  "contract_version": "ar-00/1",
  "status": "abstained",
  "missing": ["applicable_service_manual"],
  "usage": { "operation": "answer", "debited": false },
  "answer": "I cannot confirm a root cause from the published installation and product data alone.",
  "claims": [],
  "limits": [
    "No published fault-code facts for this equipment in the current corpus snapshot."
  ],
  "passages": []
}

Contract example of the abstained status. The request is a template: substitute your own model and code.

3. Get a cited answer

Each claim carries a source_id. Fetch the passage with get_hvac_source, or the page with get_hvac_document_page.

curl https://api.myleadtech.app/v1/answers \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"question":"What refrigerant does it use?","model_reference":"27TPA8"}'
{
  "contract_version": "ar-00/1",
  "status": "ok",
  "usage": { "operation": "answer", "debited": true },
  "answer": "The 27TPA8 is a Performance Series 2-stage heat pump for R-454B indoor units only.",
  "claims": [
    {
      "text": "Uses Puron Advance (R-454B) refrigerant.",
      "source_id": "chunk:1a9595df-e0cb-4dfe-83d8-504e1da1757a"
    }
  ],
  "passages": [
    {
      "source_id": "chunk:1a9595df-e0cb-4dfe-83d8-504e1da1757a",
      "document_type": "product_data",
      "pages": [1],
      "applicability": "established"
    }
  ]
}

Carrier 27TPA8, product data, page 1.

Errors

Errors return JSON with a request_id, the contract version and an error code. MCP tools return the same code.

  • 400invalid_request

    Bad parameter or unknown filter.

  • 401unauthorized

    Credential missing or invalid.

  • 403forbidden

    The credential does not allow this operation.

  • 403not_entitled

    No active API entitlement (payment_overdue, plan_unrecognised).

  • 404not_found

    Source or page not visible.

  • 409conflict

    Same idempotency key, different request.

  • 429rate_limited

    Too many answer requests per minute.

  • 429quota_exceeded

    Monthly allowance used up. Retry-After gives seconds to the end of the window.

  • 503service_closed

    Service not open for this account yet.

  • 503dependency_unavailable

    A backing service is down.

  • 504timeout

    The request took too long.

{
  "request_id": "2f6d0c1e-6b0f-4d0b-9b0e-0b6c2e5f9a11",
  "contract_version": "ar-00/1",
  "error": {
    "code": "quota_exceeded",
    "message": "The monthly operation allowance is used up."
  }
}
HTTP 429 · Retry-After: 1036800

quota_exceeded, from the contract. Nothing ran and nothing was charged.

Sandbox limits

  • 100 free units a month.
  • Equipment lookups, source and page reads never count. Neither do clarifying questions, empty results or abstentions.
  • A search costs 1 unit when it returns results. An answer costs 1 unit only when a claim rests on an established source.
  • Reuse Idempotency-Key (REST) or operation_id (MCP): a replay is never charged twice.
  • GET /v1/usage shows what you have left.
Get an API keyInstall the MCP server

Production plans are shown in your dashboard.

No card

Start free — 14 days