healthcare.dev docs
Client code

Typed clients from OpenAPI

Call the API with plain fetch or requests, or generate a typed client from the OpenAPI 3.1 spec.

There's no client package to install. The API is plain HTTPS and JSON, and its OpenAPI 3.1 spec is public at api.healthcare.dev/openapi.json (no key needed). Call it directly, or generate types and a client from the spec. For agents, connect the MCP server instead.

Plain fetch

const API = "https://api.healthcare.dev";

/** GET a path (or POST a JSON body); returns { data, meta, links }. */
async function hdev(path: string, body?: unknown) {
  const res = await fetch(new URL(path, API), {
    method: body === undefined ? "GET" : "POST",
    headers: {
      Authorization: `Bearer ${process.env.HDEV_API_KEY}`,
      "Content-Type": "application/json",
    },
    body: body === undefined ? undefined : JSON.stringify(body),
  });
  const json = await res.json();
  if (!res.ok) throw new Error(`${json.title}: ${json.detail ?? res.status}`);
  return json;
}

const { data, meta } = await hdev("/v1/codes/icd10cm/E11.9");
console.log(data.display, data.billable, meta.data_version);

const many = await hdev("/v1/codes/icd10cm/batch", { codes: ["E11.9", "I10", "NOPE"] });

Never put a live key in browser code: call the API from your server.

TypeScript types

openapi-typescript turns the spec into types, and openapi-fetch gives you a typed fetch over them:

npx openapi-typescript https://api.healthcare.dev/openapi.json -o hdev.d.ts
npm i openapi-fetch
import createClient from "openapi-fetch";
import type { paths } from "./hdev";

const hdev = createClient<paths>({
  baseUrl: "https://api.healthcare.dev",
  headers: { Authorization: `Bearer ${process.env.HDEV_API_KEY}` },
});

const { data, error } = await hdev.GET("/v1/codes/{system}/{code}", {
  params: { path: { system: "icd10cm", code: "E11.9" } },
});
if (error) console.error(error.title, error.detail);
else console.log(data.data.display, data.meta.data_version);

Regenerate the types when the changelog adds fields you want; existing fields don't change within /v1 (Versioning).

Python

With requests:

import os, requests

s = requests.Session()
s.headers["Authorization"] = f"Bearer {os.environ['HDEV_API_KEY']}"

r = s.get("https://api.healthcare.dev/v1/codes/icd10cm/E11.9")
r.raise_for_status()
body = r.json()
print(body["data"]["display"], body["meta"]["data_version"])

Or generate a typed client with openapi-python-client:

pipx run openapi-python-client generate --url https://api.healthcare.dev/openapi.json

Pages

List endpoints return one page and, when there's more, links.next: a path to request as is until it's null (Pagination).

let next: string | null = "/v1/codes/hcpcs?q=wheelchair";
while (next) {
  const page = await hdev(next);
  for (const code of page.data) console.log(code.code);
  next = page.links?.next ?? null;
}

Retries and errors

  • Errors are application/problem+json: branch on type, show detail and hint (Errors).
  • Retry 429 rate-limited, 500, 502, 503 and 504 and network errors a couple of times with exponential backoff and jitter. When the response has Retry-After (every 429, and a 503 unavailable), wait at least that many seconds.
  • Don't retry 429 quota-exceeded, spend-cap-reached or enumeration-limit: they last until the month, the cap or the day changes (Rate limits).
  • Don't retry writes that may have landed (creating a webhook or reporting an issue) without checking first.

On this page