EDI API Server User Guide

Main Endpoints

The API server provides two main endpoints for converting EDI files:

Both endpoints accept plain text request bodies and multipart/form-data uploads. For multipart requests, the parameter name must be files:

curl -F files=@"837-1.dat" -F files=@"837-2.dat" $API_URL/edi/json

You can find more examples in our GitHub repo.

See the API reference for endpoint parameters and response schemas. Expand the “200” response to view the schema for a successful response.

See the JSON schema and CSV data dictionary documentation for details about JSON fields, CSV columns, and their mappings to EDI.

JSON Object Model

An EDI input is converted into an array of business objects, such as a Claim object for 837 transactions or a Payment object for 835 transactions. There are no EDI loops or segments to handle. All segments and elements are mapped to the appropriate object fields:

[
 {
  "objectType" : "PAYMENT",
  "patientControlNumber" : "5554555444",
  "chargeAmount" : 800.00,
  "paymentAmount" : 500.00,
  "facilityCode" : {
    "subType" : "PLACE_OF_SERVICE",
    "code" : "11"
  },
  "placeOfServiceType" : "OFFICE",
  "frequencyCode" : {
    "subType" : "FREQUENCY_CODE",
    "code" : "1",
    "desc" : "Original claim"
  },
  "serviceDateFrom" : "2024-03-01",
  "serviceDateTo" : "2024-03-01",
  "patient" : {
    "person" : {
      "entityRole" : "PATIENT",
      "entityType" : "INDIVIDUAL",
      "identificationType" : "MEMBER_ID",
      "identifier" : "33344555510",
      "lastNameOrOrgName" : "BUDD",
      "firstName" : "WILLIAM"
    }
  },
  "claimStatusCode" : "1",
  "claimStatus" : "PRIMARY",
  "patientResponsibilityAmount" : 300.00,
  // Rest of the fields

You can find all fields for each object, their descriptions, and their mappings to X12 EDI segments or elements in our JSON schema documentation.

The model is denormalized, meaning that each top-level object contains information from its parent objects. For example, for 837 transactions, each claim contains information about its EDI transaction, the billing provider, and the patient. To reduce the size of the output, the transaction can optionally be converted into a separate top-level object, as described in Transaction Objects.

Many object types are reused across all transaction types.

All people and organizations (providers, payers, patients) are converted to a Party object. The Party object is used for N1 segments in 835 transactions and NM1 segments.

All healthcare codes are represented by an object consisting of a code, a description, and the code type.

Many other object types are reused across multiple transaction sets.

Review the object schemas and related examples to further understand the object model.

The output can contain objects of different types. For example, a single 835 file can contain payment objects (CLP segments) and provider adjustment objects (PLB segments). The output can also contain validation issues and control segment objects (see below).

Use the objectType field to determine the type of each top-level object:

object_type = ObjectType(obj['objectType'])
if object_type == ObjectType.PAYMENT:
    ...
elif object_type == ObjectType.PROVIDER_ADJUSTMENT:
    ...

You can find the complete example here.

Streaming Mode

The converter always runs in streaming mode, parsing the EDI input in small chunks. This allows the converter to process large files and multiple files as part of the same request. It also eliminates the need for webhooks.

The streaming mode works as follows:

  • The API server parses a chunk of EDI items from the input.
  • For each item in the chunk, the API server converts the item to JSON, NDJSON, or CSV and writes the result to the output.

The item type depends on the transaction type. For 837 transactions, each item is a claim (CLM segment). For 835 transactions, each item is a payment (CLP segment). For 834 transactions, each item is a member coverage record (INS segment). For all other transaction types, each item is the full transaction (ST segment).

The API uses a sensible default chunk size, and you can override it with the chunkSize parameter. For 835, 837, and 834 transactions, the default is 50 items per chunk. For all other transaction types, the default is 20 transactions per chunk because individual transactions can be large.

This means the API client starts receiving output as soon as the first chunk is parsed. The API server does not wait for the entire file to be parsed before sending the response.

Streaming allows the converter to convert EDI files of any size.

JSON vs NDJSON

The API server can produce well-formed JSON for input files of any size. The JSON response is an array of objects, where each object is a claim, a payment, a member coverage record, or an EDI transaction.

For large files, use a streaming parser instead of deserializing the entire JSON array into memory.

For most large-file workflows, we recommend NDJSON. The NDJSON response contains the same objects as the JSON response but without the enclosing array. Each object is written on a separate line.

Here is a Python example:

for claim_str in response.iter_lines():
    # each line is a claim object
    claim = json.loads(claim_str)
    pcn = claim['patientControlNumber']
    charge = claim['chargeAmount']
    billing_npi = claim['billingProvider']['identifier']

Set the ndjson=true parameter on the /api/edi/json endpoint to receive an NDJSON response.

Control Segments

By default, the API server returns only business objects, such as claims, payments, and members.

If you need information from X12 EDI control segments, such as ISA and GS segments, set the convertControlSegments=true parameter on the /api/edi/json endpoint.

The converter will return InterchangeControl and FunctionalGroup objects in the output stream:

[
  {
    "id": "6a41a2f8eeb7b2414b3a30c7",
    "objectType": "INTERCHANGE_CONTROL",
    "elementSeparator": "*",
    "segmentTerminator": "~",
    "authorizationInformationQualifier": "00",
    "authorizationInformation": "          ",
    ...
    "acknowledgmentRequested": "0",
    "interchangeUsageIndicator": "P",
    "componentElementSeparator": ":",
    "fileInfo": {
      "name": "835-minimal.dat",
      "url": "file:/edi-samples/edi_files/835/835-minimal.dat",
      "lastModifiedDateTime": "2026-06-27T09:24:51.832-04:00"
    }
  },
  {
    "id": "6a41a2f8eeb7b2414b3a30c9",
    "objectType": "FUNCTIONAL_GROUP",
    "functionalIdentifierCode": "HP",
    "senderCode": "SENDER CODE",
    "receiverCode": "RECEIVER CODE",
    "date": "2024-12-25",
    "time": "05:33:00",
    "controlNumber": 225426820,
    "responsibleAgencyCode": "X",
    "version": "005010X221A1"
  }
]

Note that these objects are returned in the same stream as claims and payments. Use the objectType field to distinguish between business objects and control objects.

Object IDs

The converter assigns a unique ID to each top-level object in the output stream and to each transaction object.

We use BSON ObjectId to generate the IDs. The ID consists of:

  • A 4-byte timestamp, representing the ObjectId’s creation, measured in seconds since the Unix epoch.
  • A 5-byte random value generated once per client-side process. This random value is unique to the machine and process. If the process restarts or the primary node of the process changes, this value is re-generated.
  • A 3-byte incrementing counter per client-side process, initialized to a random value. The counter resets when a process restarts.

An ObjectId ensures extremely high uniqueness without requiring a central database coordinator, and it is suitable for use in primary key fields.

Transaction Objects

By default, the converter repeats transaction-level information for each top-level object, such as claims, payments, and members.

You can use the transaction id to determine when a top-level object belongs to a new transaction.

Alternatively, you can instruct the API server to convert each transaction into a separate top-level object by setting the transactionsTopLevel parameter to true or by setting the EDI_TRANSACTION_TOP_LEVEL environment variable.

Each new transaction will then appear in the response before the claims, payments, or members that are part of that transaction, similar to the handling of control segments.

Each claim, payment, and member object will include the transaction ID in the transactionId field.

As with control segments, your code needs to branch on the objectType property to distinguish between business objects and transactions.

This approach can substantially reduce the size of the response.

If the conversion of control segments is enabled, the transaction object will contain the functionalGroupId field.

You can find an example of a JSON file with transactions at the top level in this example.

Error Handling

Always check for parsing errors in the streaming response. If a parsing error occurs at the beginning of the file, the API returns a 400 response code. For large files, an error can occur later in the stream after the API has already sent a 200 response code to the client.

Errors are serialized as objects with objectType set to ERROR. Normally, successfully converted objects have objectType set to values such as CLAIM or PAYMENT.

Example error object:

{
  "objectType": "ERROR",
  "message": "Unable to parse EDI segment",
  "fileName": "unexpected_segments.dat"
}

Your client code should branch on objectType before processing a converted object.

For example:

if claim['objectType'] == 'ERROR':
    raise Exception(f'Error parsing EDI; Error: {claim}')
else:
    # Your claim processing logic

See this Python example for more details.

For CSV output, an error line starts with the ERROR: prefix.

if line.startswith("ERROR:"):
    raise Exception(f'Error parsing EDI; Error: {line}')

See this Python example for more details.

Validation and Parsing Warnings

If you enable validation, the converter will return validation issue objects alongside all other top-level objects. Each validation issue will have objectType set to VALIDATION.

You can run validation while converting by setting validate=true on the /api/edi/json endpoint, or you can call /api/edi/validate to return only validation issues.

In non-validating mode, the converter only checks for serious errors that result in data loss, such as an invalid segment or a conversion error. By default, these warnings are written only to the log. If you set warningsInResponse=true, warnings will also be written to the response. Warnings are serialized as objects with objectType set to WARNING.

Code Descriptions

The API server can provide descriptions for all codes (CPT, HCPCS, ICD, etc.) directly in the JSON response. The latest API server version always includes the latest code description files.

Descriptions can increase the size of the response. You can disable this feature by setting the descriptions=false request parameter.

You can also disable descriptions globally by setting the codeset_enrichcodes environment variable to false. In that case, the descriptions parameter is ignored. Disabling descriptions globally also improves server startup time.

As an alternative to returning descriptions directly in the conversion response, you can use our code search API. This public API requires an API key. Your EDI Converter license can be used as the API key.

X12 EDI Codes and Qualifiers Translation

The converter translates X12 EDI codes into mnemonic constants. For example, entity identifier code 77 is translated to SERVICE_FACILITY.

These mnemonic constants are stable and can be used as enums or constants in client code.

You can find the complete list of constants with our code lookup. Enter the name of any constant to see its description and the EDI code it corresponds to, for example, SERVICE_FACILITY.