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

# Appointment statuses

> The normalized status vocabulary, how each EHR's native statuses map onto it, and how to target cancellations and no-shows

Every appointment Max AI returns carries two status fields:

| Field               | What it is                                                         |
| ------------------- | ------------------------------------------------------------------ |
| `status`            | The **normalized** value. Means the same thing on every EHR.       |
| `integrationStatus` | The EHR's own string, verbatim (`CHECKED_IN`, `WITH_PROVIDER`, …). |

`status` is what you should branch on. `integrationStatus` is for reconciling
against what the practice sees on their own calendar.

<Warning>
  Do not classify appointments by pattern-matching `integrationStatus`. A regex
  cannot tell "no cancellations this month" apart from "we do not recognise this
  EHR's word for cancelled" — and those two cases lead to opposite decisions in a
  recall campaign. Use `status`, and use `GET /appointments/statuses` to discover
  the vocabulary programmatically.
</Warning>

## The vocabulary

| `status`      | Meaning                                                                       |
| ------------- | ----------------------------------------------------------------------------- |
| `scheduled`   | Booked but not yet confirmed by the patient.                                  |
| `confirmed`   | Patient confirmed they are coming (or completed online check-in).             |
| `arrived`     | Patient is physically in the clinic — checked in, roomed, or with a provider. |
| `in_progress` | Visit actively underway. Reserved; no EHR currently maps onto it.             |
| `completed`   | Visit happened and the patient was checked out.                               |
| `cancelled`   | Cancelled before it happened, by either party.                                |
| `no_show`     | Patient did not attend and did not cancel.                                    |
| `rescheduled` | Moved; a separate appointment record carries the new slot.                    |
| `other`       | A known vendor status with no scheduling meaning (wait-listed, message left). |
| `unknown`     | Max AI has not mapped this EHR's status string.                               |

<Warning>
  `unknown` means **indeterminate**, never "not cancelled". If you are suppressing
  outreach, treat `unknown` the way you treat a missing record — exclude it from
  the campaign rather than assuming the appointment was kept.
</Warning>

## Reference endpoint

`GET /v4/appointments/statuses` returns the table above plus every native→normalized
mapping, so you never have to hardcode it. It is static reference data — identical
for every organization and safe to cache indefinitely.

```json theme={null}
{
  "success": true,
  "data": {
    "statuses": [
      { "status": "no_show", "description": "Patient did not attend and did not cancel.", "missed": true }
    ],
    "mappings": [
      { "integrationStatus": "CHECKED_IN", "status": "arrived", "ehrType": "modmed" },
      { "integrationStatus": "NO_SHOW", "status": "no_show", "ehrType": "ezderm" }
    ]
  }
}
```

The `missed` flag marks the statuses that mean the visit did not happen — the
reactivation set. Read the flag rather than hardcoding `["cancelled","no_show"]`,
so a future status joins your campaign automatically.

<Warning>
  `?statuses=` accepts only the ten normalized values above. Anything else — an
  EHR-native `integrationStatus` such as `CANCELLED`, or a near-miss spelling like
  `canceled` — is rejected with `400`, on every version including v1 and v2. It is
  deliberately not ignored: a silently-dropped status filter returns `200` with an
  empty list, and a recall campaign built on that contacts nobody while reporting
  success.
</Warning>

## Targeting cancellations and no-shows

```
GET /v4/appointments?statuses=cancelled,no_show&dateFrom=2026-01-01&dateTo=2026-06-30
```

<Note>
  **ModMed coverage note.** Max AI's ModMed sync once filtered the scheduler
  query to the attended-lifecycle statuses, so cancelled and no-show appointments
  were never written to the mirror at all. That filter was removed in MOV-2983 —
  *before* the release that shipped this endpoint, not with it — and the query now
  carries no status clause, so they come back on the same paginated pages as
  everything else, with no separate unpaginated pass to truncate. One consequence
  remains:

  * Cancellations and no-shows appear going forward, and for the sync window the
    scheduler covers — **not** retroactively for history that was never captured.
    A gap before that release is permanent; do not read it as "no cancellations".

  EZDerm has always returned cancelled and no-show statuses on its encounter feed,
  so EZDerm organizations are unaffected.
</Note>
