# Candid Health Integration

This guide explains how to model your FHIR resources for the Candid Health integration to submit professional medical claims.

## Overview  
The Candid Health integration allows you to submit professional medical claims via the `$candid-submit-claim` [custom operation](/content/docs/api/fhir/operations/custom-operations/index.html) on the [Claim](/content/docs/api/fhir/resources/claim/index.html) resource. On success, the operation returns a [ClaimResponse](/content/docs/api/fhir/resources/claimresponse/index.html) saved to Medplum with Candid's encounter and claim identifiers written back for recordkeeping. Please [contact the Medplum team](mailto:support@medplum.com) to get access to this integration.

## Creating the Claim  
The following diagram shows the resources involved in submitting a claim to Candid Health.

- patient  
- provider  
- insurance.coverage  
- item.encounter  
- subscriber  
- beneficiary  
- payor  
- practitioner  
- organization

**Claim**  
**Patient**  
**Practitioner (Rendering Provider)**

- identifier:  
  - system: http://hl7.org/fhir/sid/us-npi  
  - qualification[0].code:  
    - system: http://nucc.org/provider-taxonomy

**PractitionerRole**  
**Organization (Billing Provider)**

- identifier:  
  - system: http://hl7.org/fhir/sid/us-npi  
  - system: http://hl7.org/fhir/sid/us-ein

**Organization (Payer)**

- identifier:  
  - system: https://www.cms.gov/payer-id

**Coverage**  
- subscriberId: MEM123456789

**Encounter**

### Claim  
| Field | Description | Required |
| --- | --- | --- |
| `patient` | Reference to the Patient | Yes |
| `provider` | Reference to the rendering Practitioner | Yes |
| `billablePeriod.start` | Preferred date of service when service lines carry no individual `servicedDate` | No |
| `created` | Fallback date of service when `billablePeriod.start` is also absent | No |
| `insurance[0].coverage` | Reference to the Coverage resource | Yes |
| `diagnosis` | Array of ICD-10-CM diagnoses with `sequence` (1-based) and `diagnosisCodeableConcept` | Yes |
| `item` | Array of service lines (see below) | Yes |

Each `Claim.item` (service line) requires:

| Field | Description | Required |
| --- | --- | --- |
| `productOrService` | CPT code (system: `http://www.ama-assn.org/go/cpt`) | Yes |
| `servicedDate` | Date of service for this line. Falls back to `Claim.billablePeriod.start`, then `Claim.created` | No |
| `unitPrice` | Charge amount in USD | Yes |
| `quantity` | Number of units | Yes |
| `locationCodeableConcept` | Place of service code (system: `https://www.cms.gov/Medicare/Coding/place-of-service-codes`). If omitted, the encounter defaults to `11` (Office). | No |
| `encounter` | Reference to the Encounter resource | Yes |
| `diagnosisSequence` | Array of 1-based indices into `Claim.diagnosis` (up to 4) | Yes |
| `modifier` | CPT modifier codes | No |

### Patient  
| Field | Description | Required |
| --- | --- | --- |
| `name.family` | Last name | Yes |
| `name.given` | First name | Yes |
| `birthDate` | Date of birth | Yes |
| `gender` | `male`, `female`, `other`, or `unknown` | Yes |
| `address` | Home address with line, city, state, postalCode | Yes |

### Practitioner (Rendering Provider)  
| Field | Description | Required |
| --- | --- | --- |
| `identifier` | System must be `http://hl7.org/fhir/sid/us-npi` | Yes |
| `name` | Provider name | Yes |
| `qualification[0].code` | NUCC taxonomy code (system: `http://nucc.org/provider-taxonomy`, e.g. `207Q00000X` for Family Medicine) | Yes |

### Organization (Billing Provider)  
The billing provider Organization is linked to the Practitioner via a `PractitionerRole` resource.

| Field | Description | Required |
| --- | --- | --- |
| `identifier` | NPI identifier (system: `http://hl7.org/fhir/sid/us-npi`) | Yes |
| `identifier` | EIN/Tax ID (system: `http://hl7.org/fhir/sid/us-ein`) | Yes |
| `name` | Organization name | Yes |
| `address` | Organization address | Yes |

### Organization (Payer)  
The bot resolves the payer in Candid's directory using these identifiers in priority order:

| Priority | Identifier | System | Behavior |
| --- | --- | --- | --- |
| 1 | Candid payer UUID | `https://www.joincandidhealth.com/payer-uuid` | Direct lookup — skips name search entirely |
| 2 | CMS payer ID | `https://www.cms.gov/payer-id` | Name search filtered by ID |
| 3 | CHC payer ID | `https://www.joincandidhealth.com/chc-payerid` | Name search filtered by ID |

At least one identifier is required. `name` is also required (used in the name search for options 2 and 3). The bot hard-fails if no match is found in Candid's directory.

### Coverage (Insured)  
For insured claims, use the `CandidCoverage` profile. `Coverage.payor` must reference a payer Organization.

| Field | Description | Required |
| --- | --- | --- |
| `status` | Should be `active` | Yes |
| `subscriber` | Reference to the subscriber Patient | Yes |
| `beneficiary` | Reference to the beneficiary Patient | Yes |
| `subscriberId` | Insurance member ID | Yes |
| `payor` | Reference to the payer Organization | Yes |
| `relationship` | Patient's relationship to the subscriber (system: `http://terminology.hl7.org/CodeSystem/subscriber-relationship`, e.g. `self`, `spouse`, `child`) | Yes |
| `class` | Group number (type: `group`) and plan info | No |
| `period` | Coverage effective dates | No |

### Coverage (Self-Pay)  
For self-pay claims, set `Coverage.payor` to reference the `Patient` directly. Do **not** apply the `CandidCoverage` profile to self-pay Coverage resources. No `subscriberId` is required.

```json
{
  "resourceType": "Coverage",
  "status": "active",
  "beneficiary": { "reference": "Patient/{id}" },
  "payor": [{ "reference": "Patient/{id}" }]
}
```

The bot detects self-pay when `payor` references a `Patient` or `RelatedPerson`, skips payer lookup, and submits the claim to Candid with `responsibleParty: SELF_PAY`.

### Encounter  
| Field | Description | Required |
| --- | --- | --- |
| `identifier` | Unique encounter identifier (used as Candid's `externalId`) | Yes |
| `status` | Encounter status (e.g. `finished`) | Yes |
| `subject` | Reference to the Patient | Yes |
| `participant[0].individual` | Reference to the rendering Practitioner | Yes |
| `period.start` | Encounter start date/time | Yes |
| `period.end` | Encounter end date/time | No |

## Submitting the Claim  
The `$candid-submit-claim` [custom operation](/content/docs/api/fhir/operations/custom-operations/index.html) on `Claim` submits the claim to Candid Health's API and returns a `ClaimResponse`. Invoke it in either of these ways:

- **Instance level** — on a stored Claim: `POST {base}/fhir/R4/Claim/{id}/$candid-submit-claim`
- **Type level** — with a `Claim` in the request body: `POST {base}/fhir/R4/Claim/$candid-submit-claim`

**Instance level** (after the `Claim` has been created and stored):
```ts
const claimResponse = await medplum.post(
  medplum.fhirUrl('Claim', claim.id, '$candid-submit-claim')
);
```
Or via the FHIR REST API:
```http
POST {base}/fhir/R4/Claim/{id}/$candid-submit-claim
```
On success, the operation returns a `ClaimResponse` resource saved to Medplum. The Candid encounter and claim IDs are written back onto both the `ClaimResponse` and the original `Claim` as identifiers:
```json
{
  "resourceType": "ClaimResponse",
  "status": "active",
  "outcome": "complete",
  "request": { "reference": "Claim/{id}" },
  "insurer": { "reference": "Organization/{payer-id}" },
  "identifier": [
    { "system": "https://candidhealth.com/claim-id", "value": "..." },
    { "system": "https://candidhealth.com/encounter-id", "value": "..." }
  ],
  "total": [
    {
      "category": { "coding": [{ "system": "http://terminology.hl7.org/CodeSystem/adjudication", "code": "submitted" }] },
      "amount": { "value": 175.00, "currency": "USD" }
    }
  ]
}
```

The operation is idempotent. If an active `ClaimResponse` already exists for the `Claim`, the bot returns it immediately without re-submitting to Candid.

### Example transaction Bundle
```json
{
  "resourceType": "Bundle",
  "type": "transaction",
  "entry": [
    {
      "fullUrl": "urn:uuid:billing-org",
      "resource": {
        "resourceType": "Organization",
        "meta": {
          "profile": ["https://medplum.com/profiles/integrations/candid-health/StructureDefinition/candid-billing-organization"]
        },
        "identifier": [
          { "system": "http://hl7.org/fhir/sid/us-npi", "value": "1234567890" },
          { "system": "http://hl7.org/fhir/sid/us-ein", "value": "12-3456789" }
        ],
        "name": "Test Medical Practice LLC",
        "type": [{ "coding": [{ "system": "http://terminology.hl7.org/CodeSystem/organization-type", "code": "prov", "display": "Healthcare Provider" }] }],
        "address": [{ "use": "work", "line": ["456 Medical Center Drive", "Suite 100"], "city": "Boston", "state": "MA", "postalCode": "02101" }]
      },
      "request": { "method": "POST", "url": "Organization", "ifNoneExist": "identifier=http://hl7.org/fhir/sid/us-npi|1234567890" }
    },
    {
      "fullUrl": "urn:uuid:patient",
      "resource": {
        "resourceType": "Patient",
        "meta": {
          "profile": ["https://medplum.com/profiles/integrations/candid-health/StructureDefinition/candid-patient"]
        },
        "identifier": [{ "system": "http://hospital.example.org/patients", "value": "PAT-TEST-001" }],
        "name": [{ "use": "official", "family": "TestPatient", "given": ["Jane", "Marie"] }],
        "gender": "female",
        "birthDate": "1990-07-22",
        "address": [{ "use": "home", "line": ["789 Oak Avenue", "Apt 2A"], "city": "Cambridge", "state": "MA", "postalCode": "02139" }]
      },
      "request": { "method": "POST", "url": "Patient" }
    },
    {
      "fullUrl": "urn:uuid:practitioner",
      "resource": {
        "resourceType": "Practitioner",
        "meta": {
          "profile": ["https://medplum.com/profiles/integrations/candid-health/StructureDefinition/candid-practitioner"]
        },
        "identifier": [{ "system": "http://hl7.org/fhir/sid/us-npi", "value": "1234567890" }],
        "name": [{ "use": "official", "family": "Johnson", "given": ["Sarah", "M"], "prefix": ["Dr."] }],
        "qualification": [
          {
            "code": {
              "coding": [{ "system": "http://nucc.org/provider-taxonomy", "code": "207Q00000X", "display": "Family Medicine" }]
            }
          }
        ]
      },
      "request": { "method": "POST", "url": "Practitioner", "ifNoneExist": "identifier=http://hl7.org/fhir/sid/us-npi|1234567890" }
    },
    {
      "fullUrl": "urn:uuid:practitioner-role",
      "resource": {
        "resourceType": "PractitionerRole",
        "meta": {
          "profile": ["https://medplum.com/profiles/integrations/candid-health/StructureDefinition/candid-practitioner-role"]
        },
        "practitioner": { "reference": "urn:uuid:practitioner" },
        "organization": { "reference": "urn:uuid:billing-org" }
      },
      "request": { "method": "POST", "url": "PractitionerRole" }
    },
    {
      "fullUrl": "urn:uuid:payer-org",
      "resource": {
        "resourceType": "Organization",
        "meta": {
          "profile": ["https://medplum.com/profiles/integrations/candid-health/StructureDefinition/candid-payer-organization"]
        },
        "identifier": [{ "system": "https://www.cms.gov/payer-id", "value": "13162" }],
        "name": "1199SEIU Family of Funds",
        "type": [{ "coding": [{ "system": "http://terminology.hl7.org/CodeSystem/organization-type", "code": "ins", "display": "Insurance Company" }] }]
      },
      "request": { "method": "POST", "url": "Organization", "ifNoneExist": "identifier=https://www.cms.gov/payer-id|13162" }
    },
    {
      "fullUrl": "urn:uuid:coverage",
      "resource": {
        "resourceType": "Coverage",
        "meta": {
          "profile": ["https://medplum.com/profiles/integrations/candid-health/StructureDefinition/candid-coverage"]
        },
        "status": "active",
        "type": { "coding": [{ "system": "http://terminology.hl7.org/CodeSystem/v3-ActCode", "code": "HIP", "display": "Health Insurance Plan Policy" }] },
        "subscriber": { "reference": "urn:uuid:patient" },
        "subscriberId": "MEM-TEST-001",
        "beneficiary": { "reference": "urn:uuid:patient" },
        "relationship": { "coding": [{ "system": "http://terminology.hl7.org/CodeSystem/subscriber-relationship", "code": "self", "display": "Self" }] },
        "payor": [{ "reference": "urn:uuid:payer-org" }],
        "class": [{ "type": { "coding": [{ "system": "http://terminology.hl7.org/CodeSystem/coverage-class", "code": "group" }] }, "value": "GRP-TEST-123", "name": "Test Employer Group" }]
      },
      "request": { "method": "POST", "url": "Coverage" }
    },
    {
      "fullUrl": "urn:uuid:encounter",
      "resource": {
        "resourceType": "Encounter",
        "meta": {
          "profile": ["https://medplum.com/profiles/integrations/candid-health/StructureDefinition/candid-encounter"]
        },
        "identifier": [{ "system": "http://hospital.example.org/encounters", "value": "ENC-TEST-001" }],
        "status": "finished",
        "class": { "system": "http://terminology.hl7.org/CodeSystem/v3-ActCode", "code": "AMB", "display": "ambulatory" },
        "type": [{ "coding": [{ "system": "http://snomed.info/sct", "code": "185349003", "display": "Office visit" }] }],
        "subject": { "reference": "urn:uuid:patient" },
        "participant": [{ "individual": { "reference": "urn:uuid:practitioner" } }],
        "period": { "start": "2025-01-15", "end": "2025-01-15" }
      },
      "request": { "method": "POST", "url": "Encounter" }
    },
    {
      "fullUrl": "urn:uuid:claim",
      "resource": {
        "resourceType": "Claim",
        "meta": {
          "profile": ["https://medplum.com/profiles/integrations/candid-health/StructureDefinition/candid-claim"]
        },
        "status": "active",
        "use": "claim",
        "type": { "coding": [{ "system": "http://terminology.hl7.org/CodeSystem/claim-type", "code": "professional", "display": "Professional" }] },
        "patient": { "reference": "urn:uuid:patient" },
        "created": "2025-01-15T10:00:00Z",
        "provider": { "reference": "urn:uuid:practitioner" },
        "priority": { "coding": [{ "system": "http://terminology.hl7.org/CodeSystem/processpriority", "code": "normal" }] },
        "insurance": [{ "sequence": 1, "focal": true, "coverage": { "reference": "urn:uuid:coverage" } }],
        "diagnosis": [
          {
            "sequence": 1,
            "diagnosisCodeableConcept": { "coding": [{ "system": "http://hl7.org/fhir/sid/icd-10-cm", "code": "J06.9", "display": "Acute upper respiratory infection, unspecified" }] },
            "type": [{ "coding": [{ "system": "http://terminology.hl7.org/CodeSystem/ex-diagnosistype", "code": "principal" }] }]
          },
          {
            "sequence": 2,
            "diagnosisCodeableConcept": { "coding": [{ "system": "http://hl7.org/fhir/sid/icd-10-cm", "code": "R05.9", "display": "Cough, unspecified" }] }
          }
        ],
        "item": [
          {
            "sequence": 1,
            "diagnosisSequence": [1, 2],
            "productOrService": { "coding": [{ "system": "http://www.ama-assn.org/go/cpt", "code": "99213", "display": "Office visit, established patient, low complexity" }] },
            "servicedDate": "2025-01-15",
            "locationCodeableConcept": { "coding": [{ "system": "https://www.cms.gov/Medicare/Coding/place-of-service-codes", "code": "11", "display": "Office" }] },
            "quantity": { "value": 1 },
            "unitPrice": { "value": 125.00, "currency": "USD" },
            "net": { "value": 125.00, "currency": "USD" },
            "encounter": [{ "reference": "urn:uuid:encounter" }]
          }
        ],
        "total": { "value": 125.00, "currency": "USD" }
      },
      "request": { "method": "POST", "url": "Claim" }
    }
  ]
}
```

## Candid Health Workflow  
Once the operation is invoked, the bot runs the following steps:
1. **Encounter Creation** — The bot creates a Candid encounter with patient demographics, provider info, and all diagnoses. Candid returns an `encounterId` and `claimId`. On transient failures the bot retries up to 3 times; if the encounter already exists in Candid (identified by the FHIR `Encounter.id` as the external ID) it is fetched instead of re-created.
2. **Service Line Creation** — For each `Claim.item`, the bot creates a Candid service line with the CPT code, charge amount, and diagnosis pointers. This step is skipped if the encounter was recovered rather than freshly created to avoid duplicating service lines.
3. **ClaimResponse Creation** — The bot saves a `ClaimResponse` to Medplum with `outcome: complete` and writes the Candid `claim-id` and `encounter-id` back onto both the `ClaimResponse` and the original `Claim` as identifiers.
4. **Debug Documents** — The bot stores the outgoing Candid encounter request and the raw Candid response as `DocumentReference` resources for troubleshooting. Each document is linked to the originating Claim (via `context.related`) and Patient (via `subject`). Query them with:

```text
GET {base}/fhir/R4/DocumentReference?type=https://candidhealth.com/document-type|encounter-request

GET {base}/fhir/R4/DocumentReference?type=https://candidhealth.com/document-type|encounter-response
```

### Common Claim Status Values  
| Status | Description |
| --- | --- |
| `coded` | Claim has been coded and is ready for biller review |
| `biller_received` | Claim received by the biller |
| `waiting_for_provider` | Claim has blocking tasks requiring provider action (usually a contracting issue) |

## Related Resources  
- [Candid Health API Documentation](https://docs.joincandidhealth.com/introduction/overview)
- [Billing Documentation](/content/docs/billing/index.html)
