# Quickstart

Get a key, check one provider against one plan, read the answer, then check many pairs in one call.

Source: https://inplan.io/docs/quickstart · Updated 2026-10-30

## 1. Get a key

Sign up, open **Keys** in the dashboard and choose **Create key**. Keys start with `ip_live_`. We store only a hash of each key, so copy it when it appears.

```bash
export INPLAN_KEY="ip_live_..."
```

Want to try before you sign up? The [Playground](https://inplan.io/playground) runs on a demo key that answers for a set of sample providers.

## 2. Make your first call

Ask whether a plan lists a provider. Send the provider's NPI and the plan ID. Every request goes to `https://api.inplan.io` with your key in the `Authorization` header.

curl:

```bash
curl https://api.inplan.io/v1/check \
  -H "Authorization: Bearer $INPLAN_KEY" \
  -G -d npi=1184617268 -d plan_id=29276OH0970001
```

JavaScript:

```javascript
const url = new URL("https://api.inplan.io/v1/check");
url.search = new URLSearchParams({ npi: "1184617268", plan_id: "29276OH0970001" });

const res = await fetch(url, {
  headers: { Authorization: `Bearer ${process.env.INPLAN_KEY}` },
});
const body = await res.json();
console.log(body.data.answer, body.data.evidence);
```

Python:

```python
import os, requests

res = requests.get(
    "https://api.inplan.io/v1/check",
    params={"npi": "1184617268", "plan_id": "29276OH0970001"},
    headers={"Authorization": f"Bearer {os.environ['INPLAN_KEY']}"},
    timeout=10,
)
body = res.json()
print(body["data"]["answer"], body["data"]["evidence"])
```

This example checks Michael B. Williard, MD (NPI `1184617268`) against the 2026 marketplace plan Anthem Bronze Pathway 10600 (`29276OH0970001`). Medicare Advantage plan IDs look like `H2526-001-000`.

## 3. Read the answer

The answer sits in `data`. The evidence block is the receipt: it says which directory listed the provider, for which plan year, and when we read it.

Response (200 OK · application/json, evidence marked):

```json
{
  "request_id": "req_ws7hhhC7uSWYqEye",
  "data_as_of": "2026-07-27",
  "data": {
    "npi": "1184617268",
    "plan_id": "29276OH0970001",
    "input_plan_id": "29276OH0970001",
    "market": "aca",
    "plan_years_listed": [
      2026
    ],
    "in_network": true,
    "answer": "listed",
    "explanation": "The insurer's network directory lists this provider for this plan.",
    "evidence": [
      {
        "plan_id": "29276OH0970001",
        "plan_year": 2026,
        "network_tier": "PARTICIPATING",
        "source": {
          "type": "insurer_directory",
          "as_of": "2026-07-27"
        }
      }
    ],
    "plan_year": 2026,
    "plan": {
      "plan_name": "Anthem Bronze Pathway 10600 ($0 Virtual PCP + $0 Select Drugs)",
      "issuer": {
        "id": "29276",
        "name": "Anthem Blue Cross and Blue Shield"
      },
      "state": "OH",
      "metal_level": "Bronze",
      "plan_type": "HMO",
      "variant": null
    },
    "source": {
      "type": "insurer_directory",
      "as_of": "2026-07-27"
    },
    "as_of": "2026-07-27"
  },
  "sources": [
    {
      "type": "insurer_directory",
      "description": "Provider network directories published by health insurers",
      "as_of": "2026-10-29"
    },
    {
      "type": "plan_catalog",
      "description": "Published health plan catalogs",
      "as_of": "2026-10-28"
    }
  ],
  "notes": [
    "in_network=null means no listing was found in current directory data. It is not a statement that the provider is out of network.",
    "Network directories change. Confirm with the plan or the provider before care."
  ]
}
```

| Field | What it tells you |
| --- | --- |
| `data.in_network` | `true` when the plan's directory lists the provider. `null` when we found no listing. |
| `data.answer` | `listed` or `not_found`. Use this value to pick the words you show. |
| `data.explanation` | One plain sentence you can show to users as it is. |
| `data.evidence[]` | One entry for each listing: plan year, network tier, and for Medicare Advantage plans, whether the provider accepts new patients. |
| `evidence[].source` | The source type and `as_of`, the date we read the data. |
| `data.plan` | Plan name, insurer, state, metal level and plan type. |
| `request_id` | Unique to this request. Quote it when you contact support. |

Every check returns one of two answers:

- **LISTED · in_network: true**: The plan's network directory lists the provider. Show the plan year, tier and the date from `evidence`.
- **NOT FOUND · in_network: null**: No listing found in current directory data for this provider and plan. Ask the user to confirm with the plan. Do not show it as out of network.

## 4. Check many pairs in one call

On Builder and above, send up to 100 provider-plan pairs to `POST /v1/check/batch` in a body with the key `items`. Each pair counts as one call. A bad pair returns its own `error` and the rest of the batch still answers.

curl:

```bash
curl https://api.inplan.io/v1/check/batch \
  -H "Authorization: Bearer $INPLAN_KEY" \
  -H "Content-Type: application/json" \
  -d '{"items": [
        {"npi": "1184617268", "plan_id": "29276OH0970001"},
        {"npi": "1184617268", "plan_id": "H2526-001-000"}
      ]}'
```

JavaScript:

```javascript
const res = await fetch("https://api.inplan.io/v1/check/batch", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${process.env.INPLAN_KEY}`,
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    items: [
      {
        npi: "1184617268",
        plan_id: "29276OH0970001"
      },
      {
        npi: "1184617268",
        plan_id: "H2526-001-000"
      }
    ]
  }),
});
const body = await res.json();
const { summary, results } = body.data;
```

Python:

```python
import os, requests

res = requests.post(
    "https://api.inplan.io/v1/check/batch",
    json={
        "items": [
            {
                "npi": "1184617268",
                "plan_id": "29276OH0970001"
            },
            {
                "npi": "1184617268",
                "plan_id": "H2526-001-000"
            }
        ]
    },
    headers={"Authorization": f"Bearer {os.environ['INPLAN_KEY']}"},
    timeout=30,
)
body = res.json()
summary, results = body["data"]["summary"], body["data"]["results"]
```

Response (200 OK · response, shortened):

```json
{
  "request_id": "req_KHtLEQJ46JLKLkZZ",
  "data_as_of": "2026-10-29",
  "data": {
    "count": 4,
    "summary": {
      "listed": 2,
      "not_found": 1,
      "invalid": 1
    },
    "results": [
      {
        "index": 0,
        "npi": "1184617268",
        "plan_id": "29276OH0970001",
        "market": "aca",
        "in_network": true,
        "answer": "listed",
        "evidence": [
          {
            "plan_id": "29276OH0970001",
            "plan_year": 2026,
            "network_tier": "PARTICIPATING",
            "source": {
              "type": "insurer_directory",
              "as_of": "2026-07-27"
            }
          }
        ]
      },
      {
        "index": 1,
        "npi": "1184617268",
        "plan_id": "H2526-001-000",
        "market": "ma",
        "in_network": true,
        "answer": "listed",
        "evidence": [
          {
            "plan_id": "H2526-001-000",
            "plan_year": 2027,
            "accepting_new_patients": true,
            "provider_kind": "practitioner",
            "source": {
              "type": "plan_directory",
              "as_of": "2026-10-29"
            }
          }
        ]
      },
      {
        "index": 2,
        "npi": "1376006148",
        "plan_id": "13262AR0230002",
        "market": "aca",
        "in_network": null,
        "answer": "not_found",
        "evidence": []
      },
      {
        "index": 3,
        "npi": "1234567890",
        "plan_id": "29276OH0970001",
        "error": {
          "type": "invalid_npi",
          "title": "Invalid NPI",
          "detail": "\"1234567890\" fails the NPI check digit (Luhn with prefix 80840)."
        }
      }
    ]
  }
}
```

Read `data.summary` for the counts, then each item in `data.results`. The `index` matches the position of the pair you sent. See [Batch checks](https://inplan.io/docs/batch-checks).

## 5. Handle errors

Errors use the `application/problem+json` format (RFC 7807). Branch on `type`, show `detail` in your logs, and keep `request_id`.

| Status | Type | What to do |
| --- | --- | --- |
| 400 | `invalid_npi`, `invalid_plan_id`, `invalid_request` | Fix the input. The detail names the field. |
| 401 | `unauthorized` | Check the Authorization header and that the key is active. |
| 403 | `plan_upgrade_required`, `demo_restricted` | The endpoint needs a larger plan, or the demo key only answers for sample providers. |
| 404 | `not_found`, `plan_not_found` | We hold no record for this NPI or plan ID. |
| 429 | `rate_limited`, `quota_exceeded` | Wait for `Retry-After` seconds. Quota errors clear on the 1st of the month, UTC. |
| 503 | `busy`, `timeout` | Retry after `Retry-After` seconds. |

Every lookup response also carries rate-limit and quota headers. Calls to `/v1/status` do not count against your quota. See [Rate limits and quotas](https://inplan.io/docs/rate-limits) and [Errors](https://inplan.io/docs/errors).

## 6. Next steps

- [Answers and evidence](https://inplan.io/docs/answers-and-evidence): What each field means and how to show it.
- [API reference](https://inplan.io/docs/api): Every endpoint, parameter and response.
- [Playground](https://inplan.io/playground): Send real requests from your browser.
