Skip to main content

Claim Submission

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 on the Claim resource. On success, the operation returns a ClaimResponse saved to Medplum with Candid's encounter and claim identifiers written back for recordkeeping. Please contact the Medplum team to get access to this integration.

Creating the Claim

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

Claim

FieldDescriptionRequired
patientReference to the PatientYes
providerReference to the rendering PractitionerYes
billablePeriod.startPreferred date of service when service lines carry no individual servicedDateNo
createdFallback date of service when billablePeriod.start is also absentNo
insurance[0].coverageReference to the Coverage resourceYes
diagnosisArray of ICD-10-CM diagnoses with sequence (1-based) and diagnosisCodeableConceptYes
itemArray of service lines (see below)Yes

Each Claim.item (service line) requires:

FieldDescriptionRequired
productOrServiceCPT code (system: http://www.ama-assn.org/go/cpt)Yes
servicedDateDate of service for this line. Falls back to Claim.billablePeriod.start, then Claim.createdNo
unitPriceCharge amount in USDYes
quantityNumber of unitsYes
locationCodeableConceptPlace of service code (system: https://www.cms.gov/Medicare/Coding/place-of-service-codes). If omitted, the encounter defaults to 11 (Office).No
encounterReference to the Encounter resourceYes
diagnosisSequenceArray of 1-based indices into Claim.diagnosis (up to 4)Yes
modifierCPT modifier codesNo

Patient

FieldDescriptionRequired
name.familyLast nameYes
name.givenFirst nameYes
birthDateDate of birthYes
gendermale, female, other, or unknownYes
addressHome address with line, city, state, postalCodeYes

Practitioner (Rendering Provider)

FieldDescriptionRequired
identifierSystem must be http://hl7.org/fhir/sid/us-npiYes
nameProvider nameYes
qualification[0].codeNUCC 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.

FieldDescriptionRequired
identifierNPI identifier (system: http://hl7.org/fhir/sid/us-npi)Yes
identifierEIN/Tax ID (system: http://hl7.org/fhir/sid/us-ein)Yes
nameOrganization nameYes
addressOrganization addressYes

Organization (Payer)

The bot resolves the payer in Candid's directory using these identifiers in priority order:

PriorityIdentifierSystemBehavior
1Candid payer UUIDhttps://www.joincandidhealth.com/payer-uuidDirect lookup — skips name search entirely
2CMS payer IDhttps://www.cms.gov/payer-idName search filtered by ID
3CHC payer IDhttps://www.joincandidhealth.com/chc-payeridName 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.

FieldDescriptionRequired
statusShould be activeYes
subscriberReference to the subscriber PatientYes
beneficiaryReference to the beneficiary PatientYes
subscriberIdInsurance member IDYes
payorReference to the payer OrganizationYes
relationshipPatient's relationship to the subscriber (system: http://terminology.hl7.org/CodeSystem/subscriber-relationship, e.g. self, spouse, child)Yes
classGroup number (type: group) and plan infoNo
periodCoverage effective datesNo

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.

{
"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

FieldDescriptionRequired
identifierUnique encounter identifier (used as Candid's externalId)Yes
statusEncounter status (e.g. finished)Yes
subjectReference to the PatientYes
participant[0].individualReference to the rendering PractitionerYes
period.startEncounter start date/timeYes
period.endEncounter end date/timeNo

Submitting the Claim

The $candid-submit-claim custom operation 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):

const claimResponse = await medplum.post(
medplum.fhirUrl('Claim', claim.id, '$candid-submit-claim')
);

Or via the FHIR REST API:

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:

{
"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" }
}
]
}
note

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
{
"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:
    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

StatusDescription
codedClaim has been coded and is ready for biller review
biller_receivedClaim received by the biller
waiting_for_providerClaim has blocking tasks requiring provider action (usually a contracting issue)