Integration API

Version 1.0.0

LastMileRCM provides a webhook-based integration API that allows case management systems, EMRs, and other healthcare platforms to submit patient demographics, provider information, insurance coverage, and claims data directly into LastMileRCM for processing. The tenant is automatically resolved from your API key — no tenant identification is needed in the request body.

Base URL: https://lastmilercm.com

Authentication

All API requests must include an API key in the x-api-key header. API keys are provisioned per integration partner during onboarding.

Header:x-api-key
Format:lmr_xxxxxxxx...(min 32 characters)

Rate Limiting

Requests are rate-limited per partner. Two limits apply: 60 requests per minute and 10,000 requests per day (rolling from midnight UTC). Exceeding either limit returns 429 Too Many Requests. The daily limit is configurable per partner.

Idempotency

To prevent duplicate processing, include a unique idempotency_key in the metadata object. If a payload with the same key has already been processed, the API returns 200 with a message confirming it was already processed. No entities are re-created. If the payload is still being processed, the API returns 202.

Demo Tenants

Demo tenants have configurable limits on patient counts, claim counts, and feature access. If a limit would be exceeded by the incoming batch, the entire request is blocked and the API returns 403 Forbidden with a descriptive message indicating the current usage, limit, and how many slots remain.

Limits are checked against the batch size before processing begins — partial batches are not processed. For example, if 20/25 patients are used and a batch of 10 is submitted, the entire batch is rejected.

POST/api/webhooks/cms/inbound

Ingest Patients, Providers, Coverage & Claims

Receives patient and claim data from external case management systems. The endpoint validates the API key, processes each patient record, and creates the corresponding entities in the tenant's account.

Processing Flow

  1. 1Authentication — Validate API key and check IP allowlist
  2. 2Rate Limiting — Check per-minute request quota
  3. 3Idempotency — Skip if payload was already processed
  4. 4Tenant Resolution — Resolve tenant from the partner's default_tenant_id. The partner must have a tenant configured.
  5. 5Demo Limits — Check patient/claim caps for demo tenants
  6. 6
    Entity Processing — For each patient:
    • Deduplicate by external_id — existing patients are matched, new ones are created
    • Validate provider via NPI Registry (NPPES) lookup and enrich from registry data
    • Match payer against the Stedi payer directory
    • Create coverage with encrypted member ID
    • Create draft provider-payer enrollment (if pair doesn't exist yet)
    • Create claim with diagnoses and service lines

Patient Deduplication: Patients are matched by external_id within the tenant. If a patient with the same external_id already exists, the existing record is reused and counted as patients_existing in the response. New patients are counted as patients_created.

Draft Enrollments: When a provider-payer pair is seen for the first time, a draft enrollment is automatically created. This appears in the provider's detail page and can be activated once the provider is registered with the clearinghouse.

Request Body

patientsarrayRequired

Array of patient records to process. Always use an array, even for a single patient.

See Patient schema below

metadataobject

Optional metadata about the submission

Patient

external_idstring

Your system's unique ID for this patient. Used for deduplication — if a patient with this external_id already exists for the tenant, the existing record is reused.

Example: CMS-PAT-001

first_namestringRequired

Example: Jane

last_namestringRequired

Example: Doe

date_of_birthstringdateRequired

Example: 1985-03-15

genderstring

Normalized to M/F internally

MFMaleFemale
phonestring

Example: 603-555-0100

emailstringemail

Example: jane.doe@example.com

addressobject

Patient mailing address

Plus , , and objects (see below)

Provider

The NPI is validated against the CMS NPI Registry (NPPES). If valid, the provider record is enriched with official registry data (name, address, taxonomy, credentials). If the NPI already exists for this tenant, the existing provider is reused.

npistringRequired

National Provider Identifier (10 digits). Must be a valid, active NPI in the CMS registry.

Example: 1234567890

tax_idstring

EIN or SSN (9 digits). Encrypted at rest.

Example: 123456789

tax_id_typestring

Type of tax identifier

EINSSN
contact_emailstringemail

Contact email for enrollment communications. Encrypted at rest.

Example: billing@provider.com

Coverage

The payer name is matched against the Stedi payer directory. Only recognized payers are accepted. Matching tries exact payer_id, RPC search, and fuzzy display name matching.

payer_namestringRequired

Insurance company name. Matched against the payer directory.

Example: Blue Cross Blue Shield

payer_idstring

Optional Stedi payer ID or primary payer ID for exact matching. Takes priority over name matching.

Example: BCBS

member_idstringRequired

Insurance member/subscriber ID. Encrypted at rest with a searchable last-4 index.

Example: XYZ123456789

group_numberstring

Example: GRP-001

plan_namestring

Example: PPO Gold

coverage_typestring

Insurance coverage tier

primarysecondarytertiary

Default: primary

effective_datestringdate

Example: 2024-01-01

termination_datestringdate

Example: 2024-12-31

Claim

Requires both a provider and coverage to be successfully resolved. Claims are created in draft status.

service_datestringdateRequired

Date of service

Example: 2024-06-15

place_of_servicestring

CMS Place of Service code (e.g., 11=Office, 02=Telehealth)

Default: 11

prior_auth_numberstring

Prior authorization number if applicable

Example: AUTH-12345

total_chargenumber

Total charge amount. If omitted, calculated as sum of service line charges.

diagnosesarrayRequired

ICD-10 diagnosis codes. Decimal points are stripped automatically.

service_linesarrayRequired

CPT/HCPCS procedure codes with charges

Responses

200Success

Payload processed successfully. Returns counts of created and matched entities. No internal IDs are exposed.

successboolean

Always true

messagestring

Human-readable summary (e.g., '2 new patient(s), 1 existing patient(s) matched, 1 claim(s)')

webhook_idstringuuid

Unique ID for this webhook invocation — use for support inquiries

patient_countinteger

Total patients processed (created + existing)

processedobject

Breakdown of created vs matched entities

errorsarray

Non-fatal warnings (e.g., payer not found, NPI lookup failed). Present only if there were issues with individual records — the overall request still succeeds.

200Idempotent (already processed)

Idempotency key matched a completed payload. Returns webhook_id only — no re-processing occurs.

202In Progress

Idempotency key matched a payload that is still being processed.

400Bad Request

Invalid payload structure, missing required fields, or partner does not have a default tenant configured.

401Unauthorized

Missing or invalid API key.

403Forbidden

IP not in allowlist, or demo tenant usage limit reached (patients or claims).

429Rate Limited

Exceeded 60 requests per minute or 10,000 requests per day. Wait and retry.

Need Help?

Contact ananth@thehealthcolab.com for API key provisioning, integration support, or questions.

Code Examples

REQUEST
curl --request POST \
  --url "https://lastmilercm.com/api/webhooks/cms/inbound" \
  --header "x-api-key: lmr_your_api_key_here" \
  --header "Content-Type: application/json" \
  --data '{
  "patients": [
    {
      "external_id": "CMS-PAT-001",
      "first_name": "Jane",
      "last_name": "Doe",
      "date_of_birth": "1985-03-15",
      "gender": "F",
      "phone": "603-555-0100",
      "email": "jane.doe@example.com",
      "address": {
        "line1": "123 Main St",
        "line2": "Apt 4B",
        "city": "Manchester",
        "state": "NH",
        "postal_code": "03101"
      },
      "provider": {
        "npi": "1003000126",
        "tax_id": "061234567",
        "tax_id_type": "EIN",
        "contact_email": "billing@provider.com"
      },
      "coverage": {
        "payer_name": "Blue Cross Blue Shield",
        "member_id": "XYZ123456789",
        "group_number": "GRP-001",
        "plan_name": "PPO Gold",
        "coverage_type": "primary",
        "effective_date": "2024-01-01"
      },
      "claim": {
        "service_date": "2024-06-15",
        "place_of_service": "11",
        "prior_auth_number": "AUTH-12345",
        "diagnoses": [
          { "code": "F32.1", "type": "principal" },
          { "code": "F41.1", "type": "secondary" }
        ],
        "service_lines": [
          {
            "procedure_code": "90837",
            "description": "Psychotherapy, 60 min",
            "units": 1,
            "charge_amount": 150.00,
            "modifier_1": "95"
          }
        ]
      }
    }
  ],
  "metadata": {
    "source_system": "YourCMS",
    "idempotency_key": "batch-20240615-001"
  }
}'
RESPONSE — Single Patient200
{
  "success": true,
  "message": "Processed: 1 new patient(s), 1 claim(s)",
  "webhook_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
  "patient_count": 1,
  "processed": {
    "patients_created": 1,
    "patients_existing": 0,
    "claims_created": 1
  }
}
RESPONSE — Batch (mixed)200
{
  "success": true,
  "message": "Processed: 2 new patient(s), 1 existing patient(s) matched, 1 claim(s)",
  "webhook_id": "b2c3d4e5-f6a7-8901-bcde-f12345678901",
  "patient_count": 3,
  "processed": {
    "patients_created": 2,
    "patients_existing": 1,
    "claims_created": 1
  },
  "errors": [
    "Patient AC-PAT-ERR: Payer 'Totally Made Up Insurance' not found in payer directory"
  ]
}
RESPONSE — Idempotent200
{
  "success": true,
  "message": "Payload already processed (idempotency key matched)",
  "webhook_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890"
}
ERROR — Bad Request400
{
  "success": false,
  "message": "Invalid payload. Expected \"patients\" array with at least one patient."
}
ERROR — No Tenant Configured400
{
  "success": false,
  "message": "Integration partner does not have a default tenant configured. Contact support."
}
ERROR — Unauthorized401
{
  "success": false,
  "message": "Invalid API key"
}
ERROR — Demo Limit403
{
  "success": false,
  "message": "Demo limit exceeded. You have 45 of 50 patients used and this request would add 10 more. Contact us to upgrade.",
  "webhook_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890"
}
ERROR — Rate Limited (per minute)429
{
  "success": false,
  "message": "Rate limit exceeded. Maximum 60 requests per minute."
}
ERROR — Rate Limited (daily)429
{
  "success": false,
  "message": "Rate limit exceeded. Maximum 10,000 requests per day."
}