Ballerina EDI Module
August 22, 2026 · View on GitHub
Overview
Electronic Data Interchange (EDI) is a standard for exchanging business documents — purchase orders, invoices, shipping notices — between trading partners in a structured, machine-readable format. The two most widely used standards are X12 (North America) and EDIFACT (international).
The Ballerina edi module provides schema-driven, envelope-aware conversion between EDI text and JSON or typed Ballerina records, in both directions. The companion edi-tools CLI generates Ballerina records and ready-to-use parser code from a schema, so most users never have to call the low-level functions in this module directly.
Key features
- Schema-free envelope header inspection — the fastest path for routing and partner identification (X12 ISA/GS, EDIFACT UNB/UNH), with no schema required.
- Full envelope hierarchy parsing into typed
EdiInterchange/EdiFunctionalGroup/EdiTransactionrecords, with a fail-safe per-transaction body — process what you can and quarantine what you can't. - Transaction body parsing into JSON or typed Ballerina records (X12, EDIFACT, or any custom format).
- Serialization of JSON / records back to EDI text for outbound flows.
- Schema-driven parsing from a JSON schema — either generated from an X12 / EDIFACT spec or defined manually for partner-specific formats.
Setup
The edi module is pulled in automatically when you import it. To generate typed parsers from EDI schemas, install the companion CLI tool:
bal tool pull edi
Quickstart
The fastest path is to generate a typed parser from an EDIFACT or X12 spec using edi-tools and call the generated functions from your code.
Step 1: Generate a parser from a spec
Download the release archive for the required EDIFACT version from the UN/EDIFACT directory downloads, then run the following from your Ballerina package to generate the records and parser functions into its default module:
# 1. Convert the EDIFACT D03A ORDERS spec into a Ballerina EDI schema.
# -i is the downloaded archive (or a directory it was extracted to).
# -o is a directory; the schema is written to resources/ORDERS.json (named after the message type).
bal edi convertEdifactSchema -v d03a -t ORDERS -i d03a.zip -o resources
# 2. Generate Ballerina records and parser functions into the default module
bal edi codegen -i resources/ORDERS.json -o orders.bal
For X12 use bal edi convertX12Schema — see the edi-tools documentation. For larger projects, the generated EDI code can live in its own package within a Ballerina workspace alongside your integration.
Step 2: Use the generated code
The generated code defines typed records and parser functions in the same default module, named after the schema (an ORDERS schema produces ORDERSInterchange):
import ballerina/io;
public function main() returns error? {
string ediText = check io:fileReadString("resources/order.edi");
ORDERSInterchange interchange = check interchangeFromEdiString(ediText);
foreach var txn in interchange.transactions {
if txn.body is error {
io:println("Quarantined: ", txn.body.message());
continue;
}
io:println(txn.body);
}
}
Working with standard EDI formats
EDIFACT — prebuilt packages
For common UN/EDIFACT D03A message types you do not need to generate anything: import a ready-made
package from the ballerinax organization and call its functions directly. Each package groups
related message types by business domain.
| Package | Domain |
|---|---|
ballerinax/edifact.d03a.finance | Credit/debit advices, payment orders, invoices, ledger and tax messages. |
ballerinax/edifact.d03a.logistics | Cargo summaries, transport instructions, booking confirmations, dangerous goods. |
ballerinax/edifact.d03a.manufacturing | Metered consumption, quality data, safety hazards, waste disposal. |
ballerinax/edifact.d03a.retail | Product and price data, rebate orders, retail settlements, product inquiries. |
ballerinax/edifact.d03a.services | Insurance, healthcare, job applications, berth management, claims. |
ballerinax/edifact.d03a.shipping | Container operations, customs declarations, vessel departures, cargo reports. |
ballerinax/edifact.d03a.supplychain | Purchase orders, order responses, delivery forecasts, inventory, despatch advices. |
Each message type is available as a submodule (e.g. finance.mINVOIC, supplychain.mORDERS)
exposing the same envelope-aware API as generated code — fromEdiString / toEdiString for a
message body, and headersFromEdiString, interchangeFromEdiString, and interchangeToEdiString
for the envelope — all over typed records. Each package's default module dispatches those same
functions by message name, and adds getEDINames() and hasEnvelope().
import ballerina/io;
import ballerinax/edifact.d03a.finance.mINVOIC;
public function main() returns error? {
string ediText = check io:fileReadString("resources/invoice.edi");
mINVOIC:EDI_INVOIC_INVOICInterchange interchange = check mINVOIC:interchangeFromEdiString(ediText);
foreach mINVOIC:EDI_INVOIC_INVOICTransaction txn in interchange.transactions {
mINVOIC:EDI_INVOIC_INVOIC|error body = txn.body;
io:println(body is error ? "quarantined: " + body.message() : body.toString());
}
}
X12 — generate from your own spec
X12 message specifications are proprietary (licensed from ASC X12), so no prebuilt X12 packages are published. Instead, convert the X12 schema you are licensed to use into a Ballerina EDI schema and generate a typed parser from it, exactly like the EDIFACT quickstart above:
bal edi convertX12Schema -i schema.xsd -o resources/850-schema.json
bal edi codegen -i resources/850-schema.json -o po.bal
Exposed APIs
Most users call the generated functions rather than this module directly, but the module's public functions are available for advanced use. The table below is a cursory overview; see the Module Specification for full signatures, parameters, error types, and envelope semantics.
| Function | Purpose |
|---|---|
fromEdiString / toEdiString | Parse a transaction body to JSON / serialize JSON back to EDI text. |
x12HeadersFromEdiString / x12HeadersFromEdiFile | Schema-free peek at X12 ISA/GS headers — routing and partner identification. |
edifactHeadersFromEdiString / edifactHeadersFromEdiFile | Schema-free peek at EDIFACT UNB/UNH headers. |
headersFromEdiString / headersFromEdiFile | Schema-driven header-only parse. |
interchangeFromEdiString | Parse the full envelope hierarchy into typed records, with fail-safe per-transaction bodies. |
interchangeToEdiString | Serialize a full interchange back to EDI text (recomputes envelope counts). |
getSchema | Load and validate a JSON EDI schema into an EdiSchema. |
Customizing the generated schema
edi-tools emits the schema as a JSON file before generating code. Trading partners routinely use
variations of a standard format, so you can edit this schema to match a partner-specific layout —
adjust delimiters, segment occurrences (minOccurances / maxOccurances), field data types, or
list segments to skip in ignoreSegments — then re-run bal edi codegen to regenerate the typed
parser. A minimal schema looks like:
{
"name": "SimpleOrder",
"delimiters": {"segment": "~", "field": "*", "component": ":", "repetition": "^"},
"segments": [
{"code": "HDR", "tag": "header", "minOccurances": 1,
"fields": [{"tag": "code"}, {"tag": "orderId"}, {"tag": "organization"}, {"tag": "date"}]},
{"code": "ITM", "tag": "items", "maxOccurances": -1,
"fields": [{"tag": "code"}, {"tag": "item"}, {"tag": "quantity", "dataType": "int"}]}
]
}
The Schema Specification
documents the full grammar — delimiters, segments and segment groups, fields / components /
sub-components, the envelope declaration, and the additional configuration options.
Examples
The examples directory contains runnable end-to-end samples:
- Custom EDI schema — define a custom EDI schema and generate a typed parser from it (the codegen workflow foundation).
- Vendor router — schema-free header inspection to route inbound messages by trading partner.
- Parser to Kafka — parse an interchange with fail-safe per-transaction bodies, forward good transactions to Kafka, and quarantine the rest.
- Order generator — build and serialize a full interchange with
interchangeToEdiString, including a parse/serialize round-trip. - Acknowledgement — reply to an inbound interchange with an EDIFACT
APERAKnaming the orders that were read and the messages that were not.
Documentation
- Module Specification — the full API reference and envelope processing semantics.
- Schema Specification — the JSON grammar for EDI schemas.
- edi-tools — converting X12 / EDIFACT specs into schemas (
convertX12Schema/convertEdifactSchema), generating typed parsers (codegen), and packaging schema families as libraries (libgen).
Issues and projects
The Issues and Projects tabs are disabled for this repository as this is part of the Ballerina library. To report bugs, request new features, start new discussions, view project boards, etc., visit the Ballerina library parent repository.
This repository only contains the source code for the package.
Build from the source
Prerequisites
-
Download and install Java SE Development Kit (JDK) version 21. You can download it from either of the following sources:
Note: After installation, remember to set the
JAVA_HOMEenvironment variable to the directory where JDK was installed. -
Download and install Ballerina Swan Lake.
-
Download and install Docker.
Note: Ensure that the Docker daemon is running before executing any tests.
-
Export your GitHub personal access token with the read package permissions as follows.
export packageUser=<Username> export packagePAT=<Personal access token>
Building the source
Execute the commands below to build from the source.
-
To build the package:
./gradlew clean build -
To run the tests:
./gradlew clean test -
To build the without the tests:
./gradlew clean build -x test -
To debug package with a remote debugger:
./gradlew clean build -Pdebug=<port> -
To debug with the Ballerina language:
./gradlew clean build -PbalJavaDebug=<port> -
Publish the generated artifacts to the local Ballerina Central repository:
./gradlew clean build -PpublishToLocalCentral=true -
Publish the generated artifacts to the Ballerina Central repository:
./gradlew clean build -PpublishToCentral=true
Contribute to Ballerina
As an open-source project, Ballerina welcomes contributions from the community.
For more information, go to the contribution guidelines.
Code of conduct
All the contributors are encouraged to read the Ballerina Code of Conduct.
Useful links
- For more information go to the EDI package.
- For example demonstrations of the usage, go to Ballerina By Examples.
- Chat live with us via our Discord server.
- Post all technical questions on Stack Overflow with the #ballerina tag.