Professional Claims Submission (837P) | Medplum

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 and related resources into Stedi's Professional Claims JSON API, 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 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 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:

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:

Example transaction Bundle (organization billing, Stedi test payer)

{
  "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 renderingPractitioner. 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 supervisingPractitioner 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.