A lightweight simulator of the Stedi Healthcare Clearinghouse API for local EDI development and testing.
Drop it into any EHR dev environment that submits 837 claims through Stedi. No Stedi account, API keys, or network access required. Runs entirely in Docker — no configuration needed to get started.
docker run -d \
--name stedi-sim \
-p 3005:3005 \
-e WEBHOOK_CALLBACK_URL=http://host.docker.internal:3000/webhooks/stedi \
mbrindam/stedi-sim
Or with Docker Compose:
services:
stedi-sim:
image: mbrindam/stedi-sim
container_name: stedi_sim
ports:
- "3005:3005"
environment:
- WEBHOOK_CALLBACK_URL=http://your-backend:3000/webhooks/stedi
restart: unless-stopped
Point your EHR backend at the simulator:
STEDI_API_URL=http://localhost:3005
If both services are in the same Compose network, use the container name as the hostname and omit the external port mapping:
services:
stedi-sim:
image: mbrindam/stedi-sim
container_name: stedi_sim
environment:
- WEBHOOK_CALLBACK_URL=http://your-backend:3000/webhooks/stedi
networks:
- your_network
your-backend:
environment:
- STEDI_API_URL=http://stedi-sim:3005
networks:
- your_network
SUCCESS response/dashboard| Variable | Default | Description |
|---|---|---|
PORT | 3005 | Port the simulator listens on |
WEBHOOK_CALLBACK_URL | http://backend:3000/webhooks/stedi | Where to POST 277CA and 835 webhook events |
All paths mirror the Stedi Change Healthcare Medical Network API.
| Method | Path | Description |
|---|---|---|
POST | /change/medicalnetwork/professionalclaims/v3/submission | Submit 837P professional claim |
POST | /change/medicalnetwork/institutionalclaims/v3/submission | Submit 837I institutional claim |
POST | /change/medicalnetwork/eligibility/v3 | Real-time eligibility check (270/271) |
POST | /change/medicalnetwork/claimstatus/v2 | Synchronous claim status (276/277) |
GET | /change/medicalnetwork/reports/835/:transactionId | Retrieve generated 835 ERA |
GET | /change/medicalnetwork/reports/277/:transactionId | Retrieve generated 277CA acknowledgment |
GET | /dashboard | Monitoring dashboard (HTML) |
GET | /health | Health check |
Set tradingPartnerServiceId in your claim request to trigger a specific adjudication outcome. All scenarios are deterministic — no random failures.
tradingPartnerServiceId | Outcome | Payment | Delay | CARC |
|---|---|---|---|---|
DENY-TEST | Denied | 0% | 2s | 97 |
PARTIAL-TEST | Partial pay | 50% | 2s | 45 |
SLOW-TEST | Approved | 80% | 20s | — |
MEDICARE | Approved | 80% | 5s | — |
MEDICAID | Approved | 72% | 5s | — |
| Any other value | Approved | 80% | 2s | — |
After the configured delay, the simulator:
transaction.processed.v2 webhook (transactionSetIdentifier: "277")transactionSetIdentifier: "835")Retrieve the full report using the transactionId from the webhook payload:
GET /change/medicalnetwork/reports/835/{transactionId}
GET /change/medicalnetwork/reports/277/{transactionId}
tradingPartnerServiceId | Coverage | Deductible | OOP Max | Copay | Coinsurance |
|---|---|---|---|---|---|
DENY-TEST | Inactive | $0 | $0 | $0 | 0% |
MEDICARE | Active — Medicare Part B | $240 | $2,000 | $0 | 20% |
| Any other value | Active — PPO Plan | $1,500 | $5,000 | $30 | 20% |
{
"version": "0",
"id": "uuid",
"detail-type": "transaction.processed.v2",
"source": "stedi.core",
"account": "sim",
"time": "2024-03-15T12:00:00.000Z",
"region": "us-east-1",
"resources": [],
"detail": {
"x12": { "transactionSetIdentifier": "835" },
"transactionId": "uuid"
}
}
Headers on delivery:
Content-Type: application/json
X-Stedi-Signature: sim
The dashboard at /dashboard auto-refreshes every 5 seconds and shows:
linux/amd64 and linux/arm64 (Apple Silicon compatible).
Content type
Image
Digest
sha256:763e0c358…
Size
54.6 MB
Last updated
6 months ago
docker pull mbrindam/stedi-sim