On this page

This guide explains how to model FHIR resources and invoke the Stedi integration to submit professional (X12 837P) claims to payers.

## Overview

The Stedi integration maps a [Claim](/content/docs/api/fhir/resources/claim/index.html) and related resources into Stedi's [Professional Claims JSON API](https://www.stedi.com/docs/healthcare/api-reference/post-healthcare-claims), submits the claim to the payer, and returns submission metadata.

This workflow is handled by the **Stedi Professional Claims Bot**. Please [contact the Medplum team](mailto:support@medplum.com) to get access to this bot.

info

This integration supports **professional (837P) claims only**. Institutional (837I) and dental claims are not supported yet.

## Project secrets

Configure these secrets on the Medplum project that runs the bot:

| Secret | Type | Required | Description |
| --- | --- | --- | --- |
| `STEDI_CLAIM_API_KEY` | string | Yes | Stedi API key with permission to submit professional claims |
| `STEDI_CLAIM_TEST_MODE` | boolean | No | When `true`, sets Stedi `usageIndicator` to `T` (test). Default is `P` (production) |

note

Stedi's [test claims workflow](https://www.stedi.com/docs/healthcare/test-claims-workflow) uses a **production** API key. It does not use Stedi test API keys (prefix `test_`) the same way eligibility sandbox checks do.

## Resource model

The bot reads the `Claim` you submit and follows references to gather patient, billing provider, rendering/supervising practitioners, coverage, payer, and encounter data.

The claim links its providers directly:

- **`Claim.provider`** references the **billing provider** — an `Organization` for organization billing (the common case), or a `Practitioner` for individual billing.
- **`Claim.careTeam`** references the **practitioners who delivered care**, disambiguated by `role.coding.code` (system `http://terminology.hl7.org/CodeSystem/claimcareteamrole`):
  - **`primary`** → the **rendering** provider (the practitioner who performed the service). Required.
  - **`supervisor`** → the **supervising** provider (e.g. an MD overseeing a coach or nurse practitioner). Optional.

This separates the billing relationship (`Claim.provider`) from the clinical relationship (`Claim.careTeam`), so the billing `Organization` does not need to match any `PractitionerRole.organization` your application uses for other purposes.

### Billing as an organization vs. an individual

The 837P always requires a **billing provider**, taken from `Claim.provider`. You can bill either way:

- **As an organization** (most common for clinics): set `Claim.provider` to an `Organization` with an NPI, Tax ID (EIN), address, and phone. The claim is billed under the organization, and the rendering practitioner comes from `Claim.careTeam`.
- **As an individual provider**: set `Claim.provider` to the `Practitioner` directly. The bot then bills under the practitioner, which means the practitioner must carry the billing data itself — NPI, a tax identifier ( **EIN or SSN**), an address, and a phone. When no `careTeam` member is present, that same practitioner is also used as the rendering provider.

### Example transaction Bundle (organization billing, Stedi test payer)

```json
{
  "resourceType": "Bundle",
  "type": "transaction",
  "entry": [
    {
      "fullUrl": "urn:uuid:11111111-1111-4111-8111-111111111111",
      "resource": {
        "resourceType": "Patient",
        "name": [{ "family": "Doe", "given": ["John"] }],
        "birthDate": "1990-01-15",
        "gender": "male",
        "address": [{
          "line": ["123 Main St"],
          "city": "Boston",
          "state": "MA",
          "postalCode": "02118"
        }]
      },
      "request": { "method": "POST", "url": "Patient" }
    },
    {
      "fullUrl": "urn:uuid:22222222-2222-4222-8222-222222222222",
      "resource": {
        "resourceType": "Organization",
        "name": "Example Family Practice",
        "identifier": [
          { "system": "http://hl7.org/fhir/sid/us-npi", "value": "1999999984" },
          { "system": "http://hl7.org/fhir/sid/us-ein", "value": "12-3456789" }
        ],
        "telecom": [{ "system": "phone", "value": "6175550100" }],
        "address": [{
          "line": ["500 Clinic Way"],
          "city": "Boston",
          "state": "MA",
          "postalCode": "02118"
        }]
      },
      "request": { "method": "POST", "url": "Organization" }
    },
    {
      "fullUrl": "urn:uuid:33333333-3333-4333-8333-333333333333",
      "resource": {
        "resourceType": "Practitioner",
        "name": [{ "family": "Smith", "given": ["Alice"], "prefix": ["Dr."] }],
        "identifier": [{ "system": "http://hl7.org/fhir/sid/us-npi", "value": "1234567893" }],
        "qualification": [{
          "code": {
            "coding": [
              {
                "system": "http://nucc.org/provider-taxonomy",
                "code": "207Q00000X",
                "display": "Family Medicine"
              }
            ]
          }
        }]
      },
      "request": { "method": "POST", "url": "Practitioner" }
    },
    {
      "fullUrl": "urn:uuid:44444444-4444-4444-8444-444444444444",
      "resource": {
        "resourceType": "Practitioner",
        "name": [{ "family": "Jones", "given": ["Robert"], "prefix": ["Dr."] }],
        "identifier": [{ "system": "http://hl7.org/fhir/sid/us-npi", "value": "1999999984" }],
        "qualification": [{
          "code": {
            "coding": [
              {
                "system": "http://nucc.org/provider-taxonomy",
                "code": "207R00000X",
                "display": "Internal Medicine"
              }
            ]
          }
        }]
      },
      "request": { "method": "POST", "url": "Practitioner" }
    },
    {
      "fullUrl": "urn:uuid:55555555-5555-4555-8555-555555555555",
      "resource": {
        "resourceType": "Organization",
        "name": "Stedi Test Payer",
        "identifier": [{
          "system": "https://www.stedi.com/healthcare/network",
          "value": "STEDITEST"
        }],
        "type": [{
          "coding": [{
            "system": "http://terminology.hl7.org/CodeSystem/organization-type",
            "code": "ins",
            "display": "Insurance Company"
          }]
        }]
      },
      "request": { "method": "POST", "url": "Organization" }
    },
    {
      "fullUrl": "urn:uuid:66666666-6666-4666-8666-666666666666",
      "resource": {
        "resourceType": "Coverage",
        "status": "active",
        "subscriberId": "AMBETTER123",
        "subscriber": {
          "reference": "urn:uuid:11111111-1111-4111-8111-111111111111",
          "display": "John Doe"
        },
        "beneficiary": {
          "reference": "urn:uuid:11111111-1111-4111-8111-111111111111",
          "display": "John Doe"
        },
        "relationship": {
          "coding": [{
            "system": "http://terminology.hl7.org/CodeSystem/subscriber-relationship",
            "code": "self"
          }]
        },
        "payor": [{
          "reference": "urn:uuid:55555555-5555-4555-8555-555555555555",
          "display": "Stedi Test Payer"
        }]
      },
      "request": { "method": "POST", "url": "Coverage" }
    },
    {
      "fullUrl": "urn:uuid:77777777-7777-4777-8777-777777777777",
      "resource": {
        "resourceType": "Encounter",
        "status": "finished",
        "class": {
          "system": "http://terminology.hl7.org/CodeSystem/v3-ActCode",
          "code": "AMB",
          "display": "ambulatory"
        },
        "subject": {
          "reference": "urn:uuid:11111111-1111-4111-8111-111111111111",
          "display": "John Doe"
        },
        "period": { "start": "2026-04-01T15:00:00Z", "end": "2026-04-01T15:30:00Z" }
      },
      "request": { "method": "POST", "url": "Encounter" }
    },
    {
      "fullUrl": "urn:uuid:88888888-8888-4888-8888-888888888888",
      "resource": {
        "resourceType": "Claim",
        "status": "active",
        "type": {
          "coding": [{
            "system": "http://terminology.hl7.org/CodeSystem/claim-type",
            "code": "professional"
          }]
        },
        "use": "claim",
        "patient": {
          "reference": "urn:uuid:11111111-1111-4111-8111-111111111111",
          "display": "John Doe"
        },
        "created": "2026-04-01",
        "provider": {
          "reference": "urn:uuid:22222222-2222-4222-8222-222222222222",
          "display": "Example Family Practice"
        },
        "careTeam": [{
          "sequence": 1,
          "provider": {
            "reference": "urn:uuid:33333333-3333-4333-8333-333333333333",
            "display": "Dr. Alice Smith"
          },
          "role": { "coding": [{ "system": "http://terminology.hl7.org/CodeSystem/claimcareteamrole", "code": "primary" }]}
        },
        {
          "sequence": 2,
          "provider": {
            "reference": "urn:uuid:44444444-4444-4444-8444-444444444444",
            "display": "Dr. Robert Jones"
          },
          "role": { "coding": [{ "system": "http://terminology.hl7.org/CodeSystem/claimcareteamrole", "code": "supervisor" }]}
        }],
        "priority": { "coding": [{ "code": "normal" }] },
        "insurance": [{
          "sequence": 1,
          "focal": true,
          "coverage": { "reference": "urn:uuid:66666666-6666-4666-8666-666666666666" }
        }],
        "diagnosis": [{
          "sequence": 1,
          "diagnosisCodeableConcept": {
            "coding": [{
              "system": "http://hl7.org/fhir/sid/icd-10-cm",
              "code": "J06.9",
              "display": "Acute upper respiratory infection, unspecified"
            }]
          }
        }],
        "item": [{
          "sequence": 1,
          "productOrService": {
            "coding": [{
              "system": "http://www.ama-assn.org/go/cpt",
              "code": "99213",
              "display": "Office/outpatient visit, established patient"
            }]
          },
          "servicedDate": "2026-04-01",
          "unitPrice": { "value": 180, "currency": "USD" },
          "quantity": { "value": 1 },
          "diagnosisSequence": [1],
          "locationCodeableConcept": { "coding": [{ "code": "11" }] },
          "encounter": [{ "reference": "urn:uuid:77777777-7777-4777-8777-777777777777" }]
        }],
        "total": { "value": 180, "currency": "USD" }
      },
      "request": { "method": "POST", "url": "Claim" }
    }
  ]
}
```

## FHIR resource requirements

### Claim

| Field | Description | Required |
| --- | --- | --- |
| `patient` | Reference to the patient on the claim | Yes |
| `provider` | Reference to the **billing provider** — an `Organization` (org billing) or `Practitioner` (individual billing). Contained references (`#id`) are supported | Yes |
| `careTeam[]` with `role.coding.code` = `primary` | Reference to the **rendering**`Practitioner`. Falls back to the first `careTeam` member, then to `provider` when it is a `Practitioner` | Yes |
| `careTeam[]` with `role.coding.code` = `supervisor` | Reference to the **supervising**`Practitioner` | No |
| `insurance[0].coverage` | Reference to `Coverage` | Yes |
| `item[0].encounter[0]` | Reference to `Encounter` (used for default service date) | Yes |
| `item[]` | Service lines | Yes (at least one) |
| `item[].productOrService.coding.code` | HCPCS/CPT procedure code | Yes |
| `item[].unitPrice` or `item[].net` | Line charge (used for line and total amounts) | Yes |
| `item[].quantity` | Units of service | No (defaults to `1`) |
| `item[].diagnosisSequence` | Pointers into `Claim.diagnosis` (1-based) | No (defaults to `['1']`) |

### Common rejections and troubleshooting

Most failures are caused by missing or malformed FHIR data. The bot validates some of these up front (failing fast with a clear message); others come back from Stedi or the payer as a `400` with an `errors[]` array.
